{"record":{"id":"e343caf96e6dac1a","repo":"denoland/deno","slug":"unknown-worker-event-type","errorCode":null,"errorMessage":"Unknown worker event: \"${type}\"","messagePattern":"Unknown worker event: \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"runtime/js/11_workers.js","lineNumber":244,"sourceCode":"      }\n\n      switch (type) {\n        case 1: { // TerminalError\n          this.#status = \"CLOSED\";\n        } /* falls through */\n        case 2: { // Error\n          if (!this.#handleError(data)) {\n            throw new Error(\"Unhandled error in child worker.\");\n          }\n          break;\n        }\n        case 3: { // Close\n          log(`Host got \"close\" message from worker: ${this.#name}`);\n          this.#status = \"CLOSED\";\n          return;\n        }\n        default: {\n          throw new Error(`Unknown worker event: \"${type}\"`);\n        }\n      }\n    }\n  };\n\n  #dispatchWorkerMessage(data) {\n    let message, transferables;\n    try {\n      const v = deserializeJsMessageData(data);\n      message = v[0];\n      transferables = v[1];\n    } catch (err) {\n      const event = new MessageEvent(\"messageerror\", {\n        cancelable: false,\n        data: err,\n      });\n      setIsTrusted(event, true);\n      this.dispatchEvent(event);","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/runtime/js/11_workers.js#L226-L262","documentation":"The worker-host control protocol defines exactly three event types (1 = TerminalError, 2 = Error, 3 = Close); the poll loop's default branch in runtime/js/11_workers.js throws `Unknown worker event: \"${type}\"` for anything else. This is an internal invariant guard, reachable only when the Rust binary and the JavaScript runtime snapshot disagree on the protocol, or when embedder code injects malformed control messages through core ops. It is not caused by user-level worker code.","triggerScenarios":"A deno binary running against a mismatched or patched generated runtime JS (custom builds, stale artifacts after an interrupted upgrade); a custom deno_core embedder calling the control-channel ops directly; a corrupted snapshot cache.","commonSituations":"Mixed-version installs (binary from one release, cached snapshot/CLI artifacts from another); building deno from source with stale target/ artifacts after pulling new commits; heavily customized embedder setups.","solutions":["Reinstall or rebuild Deno so the binary and its runtime snapshot come from the same commit (remove target/, clear DENO_DIR caches on custom setups)","If embedding deno_core, never synthesize control-channel messages; use the public worker APIs","Report upstream if it reproduces on a clean official binary — it indicates a protocol regression"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"globalThis.addEventListener('unhandledrejection', (e) => {\n  if (String(e.reason).includes('Unknown worker event')) {\n    console.error('deno binary/runtime snapshot mismatch — reinstall Deno');\n    Deno.exit(1);\n  }\n});","preventionTips":["Keep the deno binary and its generated runtime artifacts from the same build — clean target/ and caches after pulling changes","In embedders, use public worker APIs; never craft control-channel messages yourself","Pin the toolchain version in CI so snapshot drift is caught before it ships"],"tags":["workers","internal-invariant","protocol","version-mismatch","deno-core"],"backgroundTag":"version-mismatch","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}