Automattic/harper · error · Error
Unhandled case: ${requestArg.type}
Error message
Unhandled case: ${requestArg.type} What it means
deserializeArg (worker side) switches on the wire tag (RequestArg.type) sent by the main thread. If the tag is not one of the known SerializableTypes — typically because main and worker threads run mismatched harper.js versions or a corrupted/hand-crafted message was posted — the switch falls through to default and throws 'Unhandled case: <type>'.
Source
Thrown at packages/harper.js/src/Serializer.ts:143
case 'Suggestion':
return Suggestion.from_json(requestArg.json);
case 'Lint':
return Lint.from_json(requestArg.json);
case 'Span':
return Span.from_json(requestArg.json);
case 'Array': {
const parsed = JSON.parse(requestArg.json);
assert(Array.isArray(parsed));
return await Promise.all(parsed.map((arg) => this.deserializeArg(arg)));
}
case 'object': {
const parsed = JSON.parse(requestArg.json);
return Object.fromEntries(
await Promise.all(parsed.map((val: any) => this.deserializeArg(val))),
);
}
default:
throw new Error(`Unhandled case: ${requestArg.type}`);
}
}
async deserialize(request: SerializedRequest): Promise<DeserializedRequest> {
return {
procName: request.procName,
args: await Promise.all(request.args.map((arg) => this.deserializeArg(arg))),
};
}
}
View on GitHub (pinned to 5fe7d5ab76)
Solutions
- Rebuild and redeploy so main thread and worker bundle the same harper.js version (bust caches/service worker)
- Check the offending type tag in the message and ensure it is one of the documented SerializableTypes
- Stop hand-crafting or mutating SerializedRequest objects; use the public WorkerLinter API
- Clear stale worker caches (service workers, HTTP cache) so old chunks don't mix with new
Example fix
// before (hand-built message)
worker.postMessage({ procName: 'lint', args: [{ json: 'x', type: 'Date' }] });
// after
const linter = new WorkerLinter();
await linter.lint('x'); Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_TYPES = ['string','number','boolean','object','Suggestion','Lint','Span','Array','undefined','bigint'];
function isValidSerializedRequest(req: any): boolean {
return req?.args?.every((a: any) => KNOWN_TYPES.includes(a?.type)) ?? false;
}
isValidSerializedRequest(request) || console.error('unknown arg type in request'); Type guard
const KNOWN_TYPES = ['string','number','boolean','object','Suggestion','Lint','Span','Array','undefined','bigint'] as const;
function isKnownRequestArg(a: unknown): a is RequestArg {
return !!a && typeof a === 'object' && KNOWN_TYPES.includes((a as any).type);
} Try / catch
try {
return await linter.lint(text);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unhandled case:')) {
// version skew or corrupted message; recreate the worker
linter.dispose();
linter = new WorkerLinter({ binary: wasmUrl });
}
throw e;
} Prevention
- Deploy main thread and worker bundles atomically; avoid mixed cached chunks
- Never hand-craft SerializedRequest messages; use the public API
- Bust service-worker/HTTP caches when upgrading harper.js
When it happens
Trigger: A SerializedRequest or nested array/object element arrives with a type tag the worker's Serializer doesn't know (e.g. 'Date', 'Map', or a tag added in a newer harper.js running against an older worker build); manually posting messages to the worker; corrupted postMessage payloads.
Common situations: Version skew between bundled main-thread harper.js and a cached/split worker chunk; custom code speaking the worker protocol directly; HMR/service-worker caches mixing old and new chunks.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Unhandled case: type undefined
- Unhandled case: ${arg}
- WorkerLinter has been disposed.
- Expected binary to be a string of url but got ${typeof binar
- Expected glue flavor to be "full" or "slim" but got ${glueFl
AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06).
Data as JSON: /api/errors/0449a059a983d8a8.
Report an issue: GitHub.