dotnet/runtime · error · Error
Invalid jsThreadBlockingMode
Error message
Invalid jsThreadBlockingMode
What it means
install_main_synchronization_context maps config.jsThreadBlockingMode to an integer via a switch that recognizes exactly four values (PreventSynchronousJSExport, ThrowWhenBlockingWait, WarnWhenBlockingWait, DangerousAllowBlockingWait). Any other value reaches the default branch and is rejected as invalid.
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 290d5ab72c)
Solutions
- Set config.jsThreadBlockingMode to exactly one of: 'PreventSynchronousJSExport', 'ThrowWhenBlockingWait', 'WarnWhenBlockingWait', 'DangerousAllowBlockingWait'.
- Omit the setting entirely so config.ts:203 applies the default 'PreventSynchronousJSExport'.
Example fix
// before config.jsThreadBlockingMode = 'PreventSync'; // after config.jsThreadBlockingMode = 'PreventSynchronousJSExport';
Defensive patterns
Strategy: validation
Validate before calling
const VALID = new Set(['PreventSynchronousJSExport', 'ThrowWhenBlockingWait', 'WarnWhenBlockingWait', 'DangerousAllowBlockingWait']);
if (config.jsThreadBlockingMode != null && !VALID.has(config.jsThreadBlockingMode)) {
throw new Error(`Invalid jsThreadBlockingMode '${config.jsThreadBlockingMode}'. Valid: ${[...VALID].join(', ')}`);
} Type guard
function isJSThreadBlockingMode(v): v is 'PreventSynchronousJSExport' | 'ThrowWhenBlockingWait' | 'WarnWhenBlockingWait' | 'DangerousAllowBlockingWait' {
return v === 'PreventSynchronousJSExport' || v === 'ThrowWhenBlockingWait' || v === 'WarnWhenBlockingWait' || v === 'DangerousAllowBlockingWait';
} Prevention
- Use exactly one of the four documented enum string values, or omit the setting to get the default.
- Validate config before passing it to the runtime rather than waiting for startup to throw.
When it happens
Trigger: Passing an unrecognized or misspelled string in config.jsThreadBlockingMode (e.g. 'PreventSync', 'Throw', a number, or undefined handling bypassed). The deputy thread calls install_main_synchronization_context with config.jsThreadBlockingMode at startup.
Common situations: Typo in the config object; copying a value from an older/newer version whose enum names differ; passing a numeric instead of the enum string.
Related errors
- Unrecognized asset behavior:${asset.behavior}, for asset ${a
- .NET runtime has failed to start, because too much memory wa
- invariant globalization mode is inactive and no ICU data arc
- max-heap-size must be an integer.\n
- method instrumentation is not enabled, please enable it with
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/54488b90c4fa45a6.
Report an issue: GitHub.