dotnet/AspNetCore.Docs · error · Error
Unknown command: ${e.data.command}
Error message
Unknown command: ${e.data.command} What it means
The web-worker message handler uses a `switch (e.data.command)` and throws `Unknown command: ${e.data.command}` in the default branch. It guards against unrecognized message types so malformed posts surface immediately rather than silently no-op'ing.
Source
Thrown at aspnetcore/blazor/blazor-with-dotnet-on-web-workers.md:335
const config = getConfig();
assemblyExports = await getAssemblyExports(config.mainAssemblyName);
} catch (err) {
startupError = err.message;
}
self.addEventListener('message', async e => {
try {
if (!assemblyExports) {
throw new Error(startupError || 'worker exports not loaded');
}
let result;
switch (e.data.command) {
case 'generateQR':
result = assemblyExports.QRGenerator.Generate(e.data.text, e.data.size);
break;
default:
throw new Error(`Unknown command: ${e.data.command}`);
}
self.postMessage({ command: 'response',
requestId: e.data.requestId, result });
} catch (err) {
self.postMessage({ command: 'response',
requestId: e.data.requestId, error: err.message });
}
});
```
## Bridge the worker to the Blazor UI
Create the following JavaScript file that manages the worker instance and exposes helper functions to Blazor.
`Clients/Client.razor.js`:
```javascriptView on GitHub (pinned to c67a80103a)
Solutions
- Match the command string exactly — the worker expects `'generateQR'`. Compare against the literal in the switch.
- Centralize command names as shared constants between main thread and worker.
- Filter out unrelated messages (e.g. by checking `e.data && e.data.requestId`) before the switch.
Example fix
// before
worker.postMessage({ command: 'generateQr', text, size, requestId });
// after
worker.postMessage({ command: 'generateQR', text, size, requestId }); Defensive patterns
Strategy: validation
Validate before calling
const COMMANDS = new Set(['generateQR']);
function isKnownCommand(cmd) {
return COMMANDS.has(cmd);
}
// Worker:
if (!isKnownCommand(e.data.command)) {
self.postMessage({ command: 'response', requestId: e.data.requestId, error: `Unknown command: ${e.data.command}` });
return;
} Type guard
function isWorkerCommand(data) {
return data && typeof data.command === 'string' && data.command === 'generateQR';
} Try / catch
// The worker already wraps in try/catch and posts the error back;
// main thread handles it:
if (resp.error && /Unknown command/.test(resp.error)) {
console.error('Protocol mismatch — check command spelling:', resp.error);
} Prevention
- Share command-name constants between worker and main thread.
- Filter unrelated messages before the switch.
- Add new commands on both sides atomically.
When it happens
Trigger: Posting any message whose `command` field is not `'generateQR'` (the only defined case). Example: a typo like `'generateQr'`, a polling message, or a framework handshake the worker doesn't expect.
Common situations: Case mismatch in command strings; evolving the protocol without updating both sides; third-party library posting to the worker (e.g. a devtools ping); stale main-thread code after adding a new command.
Related errors
- QR code size must be less than {MaxQrSize}.
- worker exports not loaded
- Validation failed. Status Code: {response.StatusCode}
- Must provide a non-empty value for the "src" attribute.
- When calling ko.fromJS, pass the object you want to convert.
AI-assisted analysis of dotnet/AspNetCore.Docs@c67a80103a (2026-08-13).
Data as JSON: /api/errors/df757a1fb9135395.
Report an issue: GitHub.