Skip to content

Build Not yet confirmed elsewhere1 publisher 3 min read Published

Exact pin on a shared singleton let one team's deploy crash another team's unchanged remote

Module Federation resolved a shared Angular Material singleton to a newer version and crashed an unchanged remote in testing, a dev.to post reports. Every per-repo check had passed. The fix was one character, a caret added to an exact version pin.

The Engineer · Build desk

How we use AI Send a correction

Illustration accompanying Exact pin on a shared singleton let one team's deploy crash another team's unchanged remote
Generated illustration
A newer singleton version failed an exact pin How one shared singleton's version reached each part. The figures are version labels, not quantities, so charting them would mislead.

Inventory offered 19.2.3, the highest, so it won. Orders pinned exactly 19.2.1, so 19.2.3 failed its check. No step in either pipeline looked at the remotes combined. mfe-guard fails when a participant will not accept the winner. The fix: '^19.2.1'.

A newer singleton version failed an exact pin
WhoHowKindClaim
Inventory remoteOffered 19.2.3, the version it was built with; the highest version wins under the default strategyexposure6
Orders remotePinned the exact version 19.2.1, so the winning 19.2.3 failed its checkconstraint8
Both teams' CI pipelinesNo step in either pipeline ever looked at the two remotes combined at runtimeconstraint12
mfe-guard CLIWorks out which singleton version will win and fails when any participant will not accept itcapability17
The one-character fixChanging '19.2.1' to '^19.2.1', then rebuilding and redeploying ordersdecision13

What happened

  • The console showed a minified ReferenceError in a component that had not changed, and the underlying Federation Runtime version error took the better part of a day to find.
  • With strictVersion the runtime throws; without it, the pinned remote silently runs on a version it was never built or tested against.
  • The post's CLI, mfe-guard, reads each remote's deployed mf-manifest.json, computes the winning singleton version, and exits with code 1 on any error.

Why it matters

  • constraint The guard runs after a deploy to the test environment, so it sees only the remote versions deployed there. A combination that first meets in production gets no check.
  • decision Teams with exact pins on shared singletons have a list to review. The tool treats each one as a crash waiting for the next patch release from a neighbouring team.
  • exposure A passing check still leaves compatible drift untested. The post's example is a remote built on ui-kit 2.13 that will run on 2.17, reported at info level only.
  • cost Adoption is one config file of manifest URLs and one CI step. The cost it targets is the debugging day the author's team lost, which the author calls the expensive part.

Nothing in the failing remote's repo had changed [1]. The trigger was a different team's remote built on an Angular Material two patch numbers ahead of the version the failing remote had pinned [24]. Of the example, the post's author wrote: "Names and versions changed. The shape of the bug is real." [4]

The highest-wins rule is what turns a patch release into a cross-team event. Under the default strategy the highest offered version becomes the winner [6], and each participant then checks that winner against its own requiredVersion [7]. An exact pin on a lower version cannot pass that check [8]. Any remote pinned exactly below the winner breaks the moment a neighbour ships a higher one [6][8].

In this case the pin was the defect. The CLI the post describes warns on singletons pinned to an exact version and calls them "a crash waiting for the next patch release" [19]. It raises an error on different major versions of a shared package [18]. We think the workable rule from this account is to align on the major and declare a range inside it.

The strictVersion flag decides how loud the failure is. With it, the runtime throws the version error. Without it, the pinned remote silently runs on a version it was never built or tested against [9]. If that happens halfway through loading a module graph, the errors point nowhere near the cause [10]. The team's first signal was a minified ReferenceError [1]. The version error took most of a day to find [3].

CI had no way to see it. Orders built on its pinned version, inventory built on the newer one, and unit, lint and e2e tests passed in each app [11]. Each pipeline was right about the one repo it could see, and no step in either looked at the combination [12].

The data to predict the crash already exists on deployed remotes. Builds on @module-federation/enhanced, which Nx, rspack, Rsbuild and Modern.js use, write an mf-manifest.json beside each remoteEntry.js [15]. It lists the version each remote ships, the requiredVersion it accepts and whether the package is a singleton [15]. The checker needs only the deployed manifest URLs, not access to other teams' source [16]. For participants without manifests, a project mode reads package.json and node_modules [23].

Transfer depends on the test environment. The guard reads whatever is deployed at the URLs it is given [17], so a pass is only as good as the match between that environment and the remote versions production will hold. This is also one account of one incident. The author says the first run against a real test environment flagged minor drift nobody had noticed [25].

What to watch

  • Whether mfe-guard's drift reports turn out to predict real failures once it runs against environments that mirror production's remote versions.
  • Whether setups that do not emit mf-manifest.json get the same coverage from project mode, which reads package.json and node_modules instead of deployed artifacts.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence55
Adoption
Insufficient
Hype gap+5
Incentives35
Confidence60
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    A remote that had not changed started crashing in the test environment with 'ReferenceError: Cannot access '_t' before initialization', and the component in the stack trace had not changed either.

    Reported SupportedView cited source
  2. [2]

    Every CI pipeline was green and every build passed; the app only broke when the shell loaded the remote next to a brand-new remote from another team.

    Reported SupportedView cited source
  3. [3]

    It took the better part of a day to find the real error underneath: a Federation Runtime error saying version 19.2.3 from inventory of shared singleton module @angular/material/autocomplete does not satisfy the requirement of orders, which needs 19.2.1.

    Reported SupportedView cited source

Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.

Add to ChatGPTAdd to Claude

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · October 14, 2026

    The Module Federation bug that passed every build and crashed in the browser

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Entities

Loading related stories