{"record":{"id":"7087dd9d0cf51337","repo":"denoland/deno","slug":"illegal-invocation-7087dd","errorCode":null,"errorMessage":"Illegal invocation","messagePattern":"Illegal invocation","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/web/12_location.js","lineNumber":248,"sourceCode":"class WorkerLocation {\n  constructor(href = null, key = null) {\n    if (key != locationConstructorKey) {\n      throw new TypeError(\"Illegal constructor\");\n    }\n    const url = new URL(href);\n    url.username = \"\";\n    url.password = \"\";\n    WeakMapPrototypeSet(workerLocationUrls, this, url);\n  }\n}\n\nObjectDefineProperties(WorkerLocation.prototype, {\n  hash: {\n    __proto__: null,\n    get() {\n      const url = WeakMapPrototypeGet(workerLocationUrls, this);\n      if (url == null) {\n        throw new TypeError(\"Illegal invocation\");\n      }\n      return url.hash;\n    },\n    configurable: true,\n    enumerable: true,\n  },\n  host: {\n    __proto__: null,\n    get() {\n      const url = WeakMapPrototypeGet(workerLocationUrls, this);\n      if (url == null) {\n        throw new TypeError(\"Illegal invocation\");\n      }\n      return url.host;\n    },\n    configurable: true,\n    enumerable: true,\n  },","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/12_location.js#L230-L266","documentation":"Deno implements `WorkerLocation` (the class of the `location` global inside Web Workers) by storing each instance's parsed URL in the module-private `workerLocationUrls` WeakMap. The prototype getter for `hash` (ext/web/12_location.js:243-251) does `WeakMapPrototypeGet(workerLocationUrls, this)` and throws `TypeError: Illegal invocation` when the lookup returns null — i.e., when the accessor runs with a receiver that is not a genuine `WorkerLocation` instance. This is Deno's version of the brand check browsers perform on WebIDL accessors.","triggerScenarios":"`Object.getOwnPropertyDescriptor(WorkerLocation.prototype, 'hash').get.call(fakeObj)`, `Object.create(WorkerLocation.prototype).hash`, or any code path that invokes the `hash` accessor with a receiver other than the real `location` instance. Normal `location.hash` reads inside a worker never throw.","commonSituations":"Generic serializers/inspectors that walk prototypes and re-invoke accessors; duck-typing or cloning attempts with `Object.create(WorkerLocation.prototype)`; test doubles built by subclassing; deep-clone or polyfill utilities that copy property descriptors.","solutions":["Access the property on the real instance: `location.hash` (or `self.location.hash` inside the worker).","If you extracted the getter, invoke it bound: `get.call(location)` or `Reflect.apply(get, location, [])`.","Stop fabricating receivers — the private WeakMap rejects any object that was not constructed by Deno internals, by design.","In generic serializer/polyfill code, read values off instances (`location.hash`) instead of re-invoking prototype accessors."],"exampleFix":"// before\nconst getHash = Object.getOwnPropertyDescriptor(WorkerLocation.prototype, 'hash').get;\nconst h = getHash.call(myFakeLocation); // TypeError: Illegal invocation\n// after\nconst h = location.hash; // read via the real global instance","handlingStrategy":"type-guard","validationCode":"// Always go through the real instance from the global scope\nconst loc = typeof location !== 'undefined' ? location : null;\nconst hash = loc?.hash; // fine: getter invoked with this === loc\n// For descriptor-driven code, brand-check the receiver first:\nconst isReal = loc != null && typeof WorkerLocation !== 'undefined' && loc instanceof WorkerLocation;","typeGuard":"function isWorkerLocation(obj) {\n  return typeof WorkerLocation !== 'undefined' && obj instanceof WorkerLocation;\n}","tryCatchPattern":null,"preventionTips":["Invoke accessors through the real instance (location.hash), never an extracted getter","Bind extracted getters to the owning instance: get.call(location)","Never fake receivers with Object.create(WorkerLocation.prototype) or subclass stubs","Avoid copying WebIDL accessor descriptors in serializers; read values off instances"],"tags":["workerlocation","hash","getter","this-binding","webidl"],"backgroundTag":"illegal-invocation","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}