dotnet/runtime · error · Error
Module.ready couldn't be redefined.
Error message
Module.ready couldn't be redefined.
What it means
Thrown by prepareEmscripten() when a moduleFactory function is passed to createDotnetRuntime and the returned module extension object contains a truthy 'ready' property. The .NET runtime manages its own Module.ready lifecycle internally; allowing user code to override it would break startup synchronization. The guard at line 300 explicitly rejects this to prevent a silent deadlock or corrupt startup state.
Solutions
- Remove the 'ready' property from the object returned by your moduleFactory function.
- If you need to know when the runtime is ready, await the promise returned by create() or run() instead of using Module.ready.
- Switch from passing a function to passing a plain config object (DotnetModuleConfig) to withModuleConfig(), avoiding the factory pattern entirely.
- If you need custom Emscripten module properties, set everything EXCEPT ready, and use the runtime's own ready promise.
Example fix
// before
const api = await createDotnetRuntime((api) => ({
ready: new Promise(resolve => { /* ... */ }),
print: console.log,
}));
// after (remove 'ready', use the returned promise)
const api = await createDotnetRuntime((api) => ({
print: console.log,
})); Defensive patterns
Strategy: validation
Validate before calling
// Validate moduleFactory return value before passing
delete moduleConfig.ready; // strip any 'ready' property
if (typeof moduleConfig === 'function') {
const test = moduleConfig(api);
if (test && 'ready' in test) {
throw new Error('Do not set ready on module config; use the runtime ready promise instead.');
}
} Type guard
function isCleanModuleConfig(config: any): boolean {
return config !== null && typeof config === 'object' && !('ready' in config);
} Prevention
- Never include a 'ready' property in your Emscripten module config for the .NET runtime.
- Prefer the high-level dotnet.create() API which handles readiness internally.
- If migrating from raw Emscripten, strip Emscripten-specific lifecycle hooks like 'ready', 'onRuntimeInitialized', etc.
When it happens
Trigger: Passing a function to createDotnetRuntime() (or the moduleFactory argument of createEmscripten) whose return value includes a 'ready' callback or promise. This is an Emscripten-style Module pattern where developers sometimes set Module.ready themselves.
Common situations: Migrating from an older version of dotnet-wasm or from raw Emscripten where setting Module.ready was common. Following outdated tutorials that show a custom module factory with a ready callback. Copying Emscripten boilerplate into the .NET runtime config.
Related errors
- Can't use moduleFactory callback of createDotnetRuntime…
- Expected to be a function
- Invalid config, resources is not set
- invariant globalization mode is inactive and no ICU data…
- Loader configuration error: 'mainAssemblyName' is required.
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/1c60352ed7de9a2a.
Report an issue: GitHub.
Appendix: source
Thrown at src/mono/browser/runtime/loader/run.ts:301
}
let emscriptenPrepared = false;
async function prepareEmscripten (moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)) {
if (emscriptenPrepared) {
return;
}
emscriptenPrepared = true;
if (ENVIRONMENT_IS_WEB && loaderHelpers.config.forwardConsole && typeof globalThis.WebSocket != "undefined") {
setup_proxy_console("main", globalThis.console, globalThis.location.origin);
}
mono_assert(emscriptenModule, "Null moduleConfig");
mono_assert(loaderHelpers.config, "Null moduleConfig.config");
// extract ModuleConfig
if (typeof moduleFactory === "function") {
const extension = moduleFactory(globalObjectsRoot.api) as any;
if (extension.ready) {
throw new Error("Module.ready couldn't be redefined.");
}
Object.assign(emscriptenModule, extension);
deep_merge_module(emscriptenModule, extension);
} else if (typeof moduleFactory === "object") {
deep_merge_module(emscriptenModule, moduleFactory);
} else {
throw new Error("Can't use moduleFactory callback of createDotnetRuntime function.");
}
await detect_features_and_polyfill(emscriptenModule);
}
export async function createEmscripten (moduleFactory: DotnetModuleConfig | ((api: RuntimeAPI) => DotnetModuleConfig)): Promise<RuntimeAPI | EmscriptenModuleInternal> {
await prepareEmscripten(moduleFactory);
if (BuildConfiguration === "Debug" && !ENVIRONMENT_IS_WORKER) {
mono_log_info(`starting script ${loaderHelpers.scriptUrl}`);
mono_log_info(`starting in ${loaderHelpers.scriptDirectory}`);View on GitHub (pinned to 60108ba66e)