dotnet/runtime · error · Error
Invalid jsThreadBlockingMode
Error message
Invalid jsThreadBlockingMode
What it means
Thrown by install_main_synchronization_context() when the jsThreadBlockingMode argument does not match any of the four known enum values (PreventSynchronousJSExport, ThrowWhenBlockingWait, WarnWhenBlockingWait, DangerousAllowBlockingWait). The switch statement's default case fires. This is a configuration or programming error: an invalid string or number was passed where a JSThreadBlockingMode enum value is required.
Solutions
- Use one of the four valid JSThreadBlockingMode string values: 'PreventSynchronousJSExport', 'ThrowWhenBlockingWait', 'WarnWhenBlockingWait', or 'DangerousAllowBlockingWait'.
- Validate the config value before passing it: check against the known set.
- If loading config from JSON, verify the spelling of the jsThreadBlockingMode field.
- Leave jsThreadBlockingMode unset to use the default (PreventSynchronousJSExport) if you don't need a specific mode.
Example fix
// before (typo in config)
const runtime = await dotnet
.withConfig({ config: { jsThreadBlockingMode: 'PreventSyncExport' } })
.create();
// after (correct enum value)
const runtime = await dotnet
.withConfig({ config: { jsThreadBlockingMode: 'PreventSynchronousJSExport' } })
.create(); Defensive patterns
Strategy: validation
Validate before calling
// Validate jsThreadBlockingMode before passing to config
const validModes = ['PreventSynchronousJSExport', 'ThrowWhenBlockingWait', 'WarnWhenBlockingWait', 'DangerousAllowBlockingWait'];
if (config.jsThreadBlockingMode && !validModes.includes(config.jsThreadBlockingMode)) {
throw new Error(`Invalid jsThreadBlockingMode: ${config.jsThreadBlockingMode}. Must be one of: ${validModes.join(', ')}`);
} Type guard
function isValidJSThreadBlockingMode(mode: string): mode is 'PreventSynchronousJSExport' | 'ThrowWhenBlockingWait' | 'WarnWhenBlockingWait' | 'DangerousAllowBlockingWait' {
return ['PreventSynchronousJSExport', 'ThrowWhenBlockingWait', 'WarnWhenBlockingWait', 'DangerousAllowBlockingWait'].includes(mode);
} Prevention
- Always use the JSThreadBlockingMode enum constants instead of raw strings.
- Validate config values loaded from external JSON before passing to the runtime.
- Omit jsThreadBlockingMode to use the safe default (PreventSynchronousJSExport).
When it happens
Trigger: Calling install_main_synchronization_context() with an unrecognized jsThreadBlockingMode value, or configuring the runtime with a misspelled or non-enum jsThreadBlockingMode string in the config. Also triggers if the config is loaded from JSON with a typo in the mode name.
Common situations: Typo in config JSON (e.g., 'PreventSyncJSExport' instead of 'PreventSynchronousJSExport'). Passing a numeric value instead of the enum string. Passing undefined or null that slips through the switch. Version mismatch where an old config uses a mode name that was renamed.
Related errors
- Cannot call synchronous C# methods.
- Invalid summary_type
- address must be a location in the native heap
- args must be an object, but got
- Argument to stringToInternedMonoStringRoot must be a string…
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/54488b90c4fa45a6.
Report an issue: GitHub.
Appendix: source
Thrown at src/mono/browser/runtime/managed-exports.ts:273
const arg2 = get_arg(args, 3);
set_arg_intptr(arg1, mono_wasm_main_thread_ptr() as any);
// sync with JSHostImplementation.Types.cs
switch (jsThreadBlockingMode) {
case JSThreadBlockingMode.PreventSynchronousJSExport:
set_arg_i32(arg2, 0);
break;
case JSThreadBlockingMode.ThrowWhenBlockingWait:
set_arg_i32(arg2, 1);
break;
case JSThreadBlockingMode.WarnWhenBlockingWait:
set_arg_i32(arg2, 2);
break;
case JSThreadBlockingMode.DangerousAllowBlockingWait:
set_arg_i32(arg2, 100);
break;
default:
throw new Error("Invalid jsThreadBlockingMode");
}
// this block is like invoke_sync_jsexport() but without assert_js_interop()
cwraps.mono_wasm_invoke_jsexport(managedExports.InstallMainSynchronizationContext!, args);
if (is_args_exception(args)) {
const exc = get_arg(args, 0);
throw marshal_exception_to_js(exc);
}
return get_arg_gc_handle(res) as any;
} catch (e) {
mono_log_error("install_main_synchronization_context failed", e);
throw e;
}
}
export function invoke_async_jsexport (managedTID: PThreadPtr, method: MonoMethod, args: JSMarshalerArguments, size: number): void {
assert_js_interop();
if (!WasmEnableThreads || runtimeHelpers.isManagedRunningOnCurrentThread) {View on GitHub (pinned to 60108ba66e)