# Runtime

This page collects runtime-related error codes and common troubleshooting guidance.

## Error Codes

- [RUNTIME-001](#runtime-001)
- [RUNTIME-002](#runtime-002)
- [RUNTIME-003](#runtime-003)
- [RUNTIME-004](#runtime-004)
- [RUNTIME-005](#runtime-005)
- [RUNTIME-006](#runtime-006)
- [RUNTIME-007](#runtime-007)
- [RUNTIME-008](#runtime-008)
- [RUNTIME-009](#runtime-009)
- [RUNTIME-010](#runtime-010)
- [RUNTIME-012](#runtime-012)
- [RUNTIME-013](#runtime-013)
- [RUNTIME-014](#runtime-014)
- [RUNTIME-015](#runtime-015)

## RUNTIME-001


# Failed to get remoteEntry exports. 

Copy Markdown

- Error Code: `RUNTIME-001`


### Reasons

When the producer entry file is loaded normally, the producer will be registered in the global object (globalThis/window), which can be accessed through window\[remoteEntryKey].

However, during this loading process, registered producers are inaccessible. There are four possible causes for this error:

1. The remoteEntryUrl is not right.
2. The remoteEntry file does not mount the container correctly.
3. Network problem, the resource cannot be accessed.
4. The remote type is a different format and not specified in either the plugin or in the `init` for the remotes details.

### Solutions

There are corresponding solutions for the reasons:

1. Check whether the remoteEntryUrl is correct.

- If using manifest, check the publicPath and remoteEntry.name fields in the manifest

2. If the project builder is rspack, check whether [runtimeChunk](https://rspack.dev/config/optimization#optimizationruntimechunk) is set in the final build configuration. If so, delete this configuration.
3. Check if the resource is externally accessible.
4. Loading a ESM remote from a non-esm host

- setting `type: 'module'` on the remote config

### Getting More Detailed Error Information

If you have confirmed that `window[remoteEntryKey]` does not exist (i.e. the script failed to register the container), but there is no clear error message in the console, it may be because the producer script is a cross-origin resource. Browsers hide error details for cross-origin scripts by default (`filename`, `lineno`, and `message` are all empty).

You can add a `crossorigin` attribute to the script via the [`createScript`](/plugin/dev/index.md#createscript) hook, provided that the producer server has `Access-Control-Allow-Origin` configured.

First, create the runtime plugin file:

```ts title="script-crossorigin-plugin.ts"
import { ModuleFederationRuntimePlugin } from '@module-federation/runtime/types';

export default function MFScriptPlugin(): ModuleFederationRuntimePlugin {
  return {
    name: 'script-crossorigin-plugin',
    createScript({ url }) {
      const script = document.createElement('script');
      script.src = url;
      script.crossOrigin = 'anonymous';
      return script;
    },
    // If preloadRemote is used in your project, also implement createLink to keep
    // crossorigin consistent. Without this, the preload (no-cors) and actual load
    // (cors) will have different cache keys, causing the preload to be wasted.
    createLink({ url, attrs }) {
      const link = document.createElement('link');
      link.setAttribute('href', url);
      link.setAttribute('crossorigin', 'anonymous');
      if (attrs) {
        Object.entries(attrs).forEach(([key, value]) => {
          if (key !== 'crossorigin') {
            link.setAttribute(key, String(value));
          }
        });
      }
      return link;
    },
  };
}
```

Then register the plugin:


**Build Plugin**

Register via the `runtimePlugins` field in your build config:
```ts title="rspack.config.ts"
const path = require('path');
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'host',
      remotes: { /* ... */ },
      runtimePlugins: [
        path.resolve(__dirname, './script-crossorigin-plugin.ts'),
      ],
    }),
  ],
};
```


**Runtime API**

Register via the `plugins` field in the `init` API:
```ts title="index.ts"
import { init } from '@module-federation/runtime';
import MFScriptPlugin from './script-crossorigin-plugin';

init({
  name: 'host',
  remotes: [/* ... */],
  plugins: [MFScriptPlugin()],
});
```


Once added, runtime exceptions thrown by cross-origin scripts will include the full `filename`, `lineno`, and `message`, making it easier to locate the specific error.

:::warning

- After adding this plugin, you must also set `output.crossOriginLoading` to `'anonymous'` in the build config of **all producers**, otherwise preloading will stop working.

```js
// webpack.config.js / rspack.config.js (producer side)
module.exports = {
  output: {
    crossOriginLoading: 'anonymous',
  },
};
```

- If the server does not have CORS headers configured, adding the `crossorigin` attribute will instead cause the script to fail to load (network error). Confirm the server is correctly configured before using this approach.

:::

## RUNTIME-002


# The remote entry interface does not contain "init" 

Copy Markdown

- Error Code: `RUNTIME-002`


### Reasons

Cannot get the producer container `init` function.

A normal producer container exports `{ get, init }`. In this load, `init` is `undefined`, so an error is thrown.

### Solutions

Troubleshoot in the following order:

1. Before loading the producer, run window\[remoteEntryKey] in `terminal` to check whether this object is already occupied. If so, rename the producer [name](/configure/name.md#name)
2. If the project builder is rspack, check whether [runtimeChunk](https://rspack.dev/config/optimization#optimizationruntimechunk) is set in the final build configuration. If so, delete this configuration.

## RUNTIME-003


# Failed to get manifest. 

Copy Markdown

- Error Code: `RUNTIME-003`


### Reasons

Failed to load manifest.

### Solutions

1. Check whether the manifestUrl can be accessed normally
2. Check whether the manifestUrl has cross-origin issues

## RUNTIME-004


# Failed to locate remote. 

Copy Markdown

- Error Code: `RUNTIME-004`


### Reasons

No matching remote module found. This error may be caused by the following reasons:

1. The producer information is not registered in the consumer
2. requestId uses the wrong alias or name
3. A `beforeRequest` hook is registered and does not return the correct data

### Solutions

1. Check whether the producer information for this request is registered in the consumer
2. Compare whether the registered producer information (name/alias) is consistent with requestId
3. Check whether a `beforeRequest` hook is registered and fix the corresponding runtime plugin

## RUNTIME-005


# Invalid loadShareSync function call from bundler runtime 

Copy Markdown

- Error Code: `RUNTIME-005`


### Reasons

After Shared is set, the corresponding dependent library will be determined to be an asynchronous module. If the asynchronous entry is not enabled and `eager: true` is not set, then this error will occur.

### Solutions

Just choose one of the two:

1. Enable asynchronous entry

If the `@module-federation/modern-js-v3` plug-in is used, the corresponding asynchronous entry will be enabled based on the builder type by default.

But if it is [build mode](https://modernjs.dev/en/guides/concept/entries.html#build-mode-entry), then you still need to set the asynchronous entry manually.

Next, we will demonstrate how to enable asynchronous entry.

Create the bootstrap.js file and copy the contents of the original entry file here:

```diff title="bootstrap.js"
+ import React from 'react';
+ import ReactDOM from 'react-dom';
+ import App from './App';
+ ReactDOM.render(<App />, document.getElementById('root'));
```

Modify the content of the original entry file and reference bootstrap.js instead:

```diff title="index.js"
+ import('./bootstrap');
- import React from 'react';
- import ReactDOM from 'react-dom';
- import App from './App';
- ReactDOM.render(<App />, document.getElementById('root'));
```

2. Set shared `eager: true`

## RUNTIME-006


# Invalid loadShareSync function call from runtime 

Copy Markdown

- Error Code: `RUNTIME-006`


### Reasons

The current shared dependency is not loaded, so `loadShareSync` cannot be used.

### Solutions

Just choose one of the two:

1. Use `loadShare` instead of `loadShareSync`
2. Provide the [lib](/guide/runtime/runtime-api.md#loadshare) function to the current shared dependency

## RUNTIME-007


# Failed to get remote snapshot. 

Copy Markdown

- Error Code: `RUNTIME-007`


### Reasons

Remote entry is set to a version number rather than a resource URL, and the deployment platform does not deliver the correct data.

### Solutions

Check whether globalSnapshot contains an object with key `${moduleName}:${moduleInfo.version}`. If not, check whether there is an issue in the deployment platform data delivery pipeline.

## RUNTIME-008


# Failed to load script resources. 

Copy Markdown

- Error Code: `RUNTIME-008`


### Reasons

The remote entry script failed to load. The error message includes a specific failure reason, which falls into one of two categories:

**1. ScriptNetworkError — network-level failure**

The script file could not be downloaded. Common causes:

- Incorrect resource URL (server returns 404)
- Network instability or request timeout
- Cross-origin (CORS) misconfiguration
- CDN node unavailability

**2. ScriptExecutionError — runtime error during script execution**

The script file downloaded successfully, but its IIFE threw a runtime exception during execution. The error message will contain `ScriptExecutionError` along with the original exception (e.g. `TypeError: ...`). Common causes:

- Incompatible syntax in the producer's code (e.g. unsupported browser APIs)
- Producer entry relies on a global variable that was not correctly initialized
- Corrupted or incomplete build output

### Solutions

**For ScriptNetworkError:**

1. Open the resource URL from the error message directly in the browser to confirm it is accessible
2. Verify the producer's `publicPath` and `remoteEntry` address configuration
3. Check for CORS issues; if needed, configure CORS on the server or use the [`createScript`](/plugin/dev/index.md#createscript) hook to add a `crossOrigin` attribute
4. For flaky networks, add a retry mechanism — refer to [Runtime retry](/plugin/plugins/retry-plugin.md)

**For ScriptExecutionError:**

1. Inspect the original exception in the error message (`TypeError` / `SyntaxError`, etc.) to locate the specific error in the producer's entry file
2. Verify that the producer's build target is compatible with the consumer's browser support range
3. Download the remote entry file from the browser DevTools Network panel and execute it manually to reproduce the error

:::tip
A `ScriptExecutionError` means the script was downloaded successfully — retrying will not fix this type of error. Focus on investigating compatibility or runtime errors in the producer's code first.
:::

### Getting More Detailed Error Information

Prior to **v2.3.0**, RUNTIME-008 error messages may not include specific exception details. If the error message is not descriptive enough, refer to "[RUNTIME-001 Getting More Detailed Error Information](#getting-more-detailed-error-information)" for how to add the `crossorigin` attribute to retrieve the full error stack.

## RUNTIME-009


# Please call createInstance first. 

Copy Markdown

- Error Code: `RUNTIME-009`


### Reason

Not use build plugin, but directly call runtime api.

### Solution

If the build plugin is used, an MF instance will be automatically created and stored in memory when the project starts. You can directly call methods of the MF instance via the .

```ts
import { loadRemote } from '@module-federation/enhanced/runtime';

loadRemote('remote1');
```

If the build plugin is not used, you need to manually create an MF instance before calling the corresponding API.

```ts
import { createInstance } from '@module-federation/enhanced/runtime';

const mf = createInstance({
  name: 'host',
  remotes: [
    {
      name: 'remote1',
      entry: 'http://localhost:2001/vmok-manifest.json',
    },
  ],
});

mf.loadRemote('remote1');
```

:::tip ModuleFederation instance

An object created by the `ModuleFederation` class that contains all runtime functionality. You can enter `__FEDERATION__.__INSTANCES__` in the console to view the full instance information.

:::

## RUNTIME-010


# The name option cannot be changed after initialization. If you want to create a new instance with a different name, please use "createInstance" api. 

Copy Markdown

- Error Code: `RUNTIME-010`


### Reason

`initOptions` was called with a `name` different from the one used during initialization. The `name` is the unique identifier of the instance and cannot be changed after initialization.

### Solution

- If you need an instance with a different `name`, use the `createInstance` API to create a new instance instead of modifying the existing one.
- If changing the `name` is not required, omit the `name` field in the `initOptions` call or keep it consistent with the value used during initialization.

## RUNTIME-012


# The getter for the shared module is not a function. This may be caused by setting "shared.import: false" without the host providing the corresponding lib. 

Copy Markdown

- Error Code: `RUNTIME-012`


### Reason

When loading a shared module, the local `getter` is not a function (it is `undefined` or another non-function type).

When `loadShare` returns `false` — meaning the remote did not provide the shared module — the runtime falls back to the local `getter` to resolve the module. If the `getter` is not a function at that point, neither the remote nor the local fallback can supply the module, and this error is thrown.

**Most common cause**: `import: false` is set for the shared module in one of the applications, which tells the bundler not to include that module locally. In this case the host app **must** provide the module via a `lib` function — if no host provides it, the fallback has nothing to call.

### Solution

1. **Check the `shared.import` configuration**

   If you set `import: false` for this shared module in any application, you must ensure the host provides a corresponding `lib` function, for example:

   ```ts title="host/webpack.config.ts"
   new ModuleFederationPlugin({
     name: 'host',
     shared: {
       react: {
         singleton: true,
         lib: () => require('react'), // host must provide lib
       },
     },
   });
   ```

2. **Remove `import: false`**

   If the optimization is not required, remove `import: false` and let the bundler handle the dependency automatically.

3. **Verify shared module name and version range**

   Make sure the shared module name and version range are consistent between the host and all remotes, so a match can be found and the fallback is never reached with an empty `getter`.

## RUNTIME-013


# The manifest is not a valid Module Federation manifest. 

Copy Markdown

- Error Code: `RUNTIME-013`


### Reason

The manifest can be reached and parsed as JSON, but it is not a valid Module Federation manifest.

The most common case is that required fields such as `metaData`, `exposes`, or `shared` are missing. This usually means the URL returned the wrong JSON, a gateway returned incomplete data, or the producer did not emit a valid MF manifest.

### Solution

1. Open the manifestUrl from the error message directly and confirm that it returns an MF manifest, not another business JSON response or an empty object
2. Check that manifest output is enabled in the producer and that the build artifact contains `metaData`, `exposes`, and `shared`
3. Check whether a gateway, deployment platform, or proxy rewrote the manifest response
4. If the observability plugin is enabled, start from `diagnosis.facts.url` and `diagnosis.actions`

## RUNTIME-014


# The remote does not expose the requested module. 

Copy Markdown

- Error Code: `RUNTIME-014`


### Reason

The producer entry was loaded and initialized, but the producer did not export the requested expose.

Common causes include:

1. The expose name requested by the consumer is wrong
2. The producer build config does not declare this expose
3. The `./` prefix, letter case, or alias does not match
4. The consumer is using an old build artifact and the latest producer expose has not been deployed

### Solution

1. Compare the consumer `loadRemote('remote/expose')` request with the producer `exposes` config
2. Check whether the expose needs the `./` prefix, and verify that the case matches exactly
3. If loading through manifest, check whether the manifest `exposes` list contains the module
4. If the observability plugin is enabled, inspect `diagnosis.facts.expose` and the related `check-expose` action

## RUNTIME-015


# Remote container initialization failed. 

Copy Markdown

- Error Code: `RUNTIME-015`


### Reason

The producer entry was loaded, but container initialization failed.

This usually happens while the producer runs `init`, for example because shared dependency initialization failed, shareScope data did not match expectations, or the producer entry threw an internal error.

### Solution

1. Read the original error in the message; it points to the actual failure thrown during `init`
2. Check shared config between the host and producer, especially shareScope, singleton, strictVersion, requiredVersion, and eager
3. Confirm that the producer remoteEntry type and global name match the consumer config
4. If the observability plugin is enabled, inspect `summary.phases.remoteEntry`, `diagnosis.facts`, and the `check-shared-provider` action

## Common Issues (No Error Code)

### Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

#### Error Message

:::danger Browser Error Message
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

You might have mismatching versions of React and the renderer (such as React DOM)

You might be breaking the Rules of Hooks

You might have more than one copy of React in the same app
:::

:::danger Browser Error Message
Uncaught TypeError: Cannot read properties on null (reading `useState`)
:::

#### Solution

This error is a React multi-instance problem, which usually occurs when react does not reuse the same instance.
This problem can be avoided by setting `shared` and setting `singleton: true` singleton mode.

```ts title="modern.config.js"
{
    ...
    new ModuleFederationPlugin({
            ...,
         // Default basic configuration
         // shared: [
         //   'react',
         //   'react-dom',
         //   'my-custom-module'
         // ]

         // Configuration with more specificity
            shared: {
                react: { singleton: true, },
                'react-dom': { singleton: true, },
                'my-custom-module': { singleton: true, },
                ...
            },
        })
      ])
  }
```

### HMR failed

- Use [React Developer Tools](https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)

- If shared is provided from online host, use [Module Federation DevTools](/guide/debug/chrome-devtool.md), and click `Enable HMR` button .

![](/static/image/mf-devtool-hmr.0e91908fec.jpg)
### Subpath imports are not shared (duplicate dependency loaded)

#### Symptom

- The browser downloads two copies of the same package (e.g. `react-dom`)
- React throws "Invalid hook call" or hydration mismatch errors
- `loadShare` returns `false` for subpath imports like `react-dom/client`

#### Root cause

The `shared` config only lists the exact package name, e.g. `'react-dom'`. Module Federation intercepts imports at build time. An exact name only intercepts `import 'react-dom'`; subpath imports such as `import { createRoot } from 'react-dom/client'` bypass the shared config and are bundled locally.

#### Solution

Use a **trailing slash** to enable prefix matching for any package that exposes subpaths:

```ts title="rspack.config.ts"
shared: {
  react: { singleton: true },
  'react-dom': { singleton: true },      // exact match — only 'react-dom'
  'react-dom/': { singleton: true },     // prefix match — 'react-dom/client', 'react-dom/server', ...
  'react/': { singleton: true },         // prefix match — 'react/jsx-runtime', 'react/jsx-dev-runtime', ...
}
```

The same applies to scoped packages (`'@scope/package/'`) and utility libraries (`'lodash/'`).

### A preload for '[http://resource-url](http://resource-url)' is found, but is not used because the request credentials mode does not match. Consider taking a look at crossorigin attribute.

#### Reason

When the producer URL is a manifest, loading this producer module will automatically preload the corresponding resources. If the above warning occurs, it is because the default preload does not configure credentials, while the actual `load remote script` carries the corresponding credentials, causing the preload to fail.

#### Solution

Add a runtime plugin via [runtimePlugins](/configure/runtimeplugins.md) and configure the `crossorigin` attribute in the [createLink](/plugin/dev/index.md#createlink) hook. Its value needs to be consistent with the actual `load script`.

For example, to modify the crossorigin attribute of the preloaded link to `anonymous`:

```ts title="runtimePlugin.ts"
import { ModuleFederationRuntimePlugin } from '@module-federation/runtime/types';

export default function MFLinkPlugin(): ModuleFederationRuntimePlugin {
  return {
    name: 'link-plugin',
    createLink({ url }) {
      const link = document.createElement('link');
      link.setAttribute('href', url);
      link.setAttribute('rel', 'preload');
      link.setAttribute('as', 'script');
      link.setAttribute('crossorigin', 'anonymous');
      return link
    }
  };
}
```
