{"record":{"id":"c082ed2fd1ec1f17","repo":"denoland/deno","slug":"err-inspector-not-connected","errorCode":"ERR_INSPECTOR_NOT_CONNECTED","errorMessage":"Session is not connected","messagePattern":"Session is not connected","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/inspector.js","lineNumber":194,"sourceCode":"      this.#isDraining = false;\n    }\n  }\n\n  post(method, params, callback) {\n    validateString(method, \"method\");\n    if (!callback && typeof params === \"function\") {\n      callback = params;\n      params = null;\n    }\n    if (params) {\n      validateObject(params, \"params\");\n    }\n    if (callback) {\n      validateFunction(callback, \"callback\");\n    }\n\n    if (!this.#connection) {\n      throw new ERR_INSPECTOR_NOT_CONNECTED();\n    }\n    const id = this.#nextId++;\n    const message = { id, method };\n    if (params) {\n      message.params = params;\n    }\n    if (callback) {\n      this.#messageCallbacks.set(id, callback);\n    }\n    op_inspector_dispatch(this.#connection, JSONStringify(message));\n  }\n\n  disconnect() {\n    if (!this.#connection) {\n      return;\n    }\n    op_inspector_disconnect(this.#connection);\n    this.#connection = null;","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/inspector.js#L176-L212","documentation":"Session.post(method, params, callback) dispatches a Chrome DevTools Protocol message. After argument validation (params object, callback function), it checks the private #connection and throws ERR_INSPECTOR_NOT_CONNECTED when there is no live connection — post() ran before connect()/connectToMainThread(), or after disconnect() cleared the connection and pending state.","triggerScenarios":"const s = new inspector.Session(); s.post('Runtime.enable'); — no connect() call. Also posting from a timer or callback that fires after you already called disconnect().","commonSituations":"Copying CDP snippets that omit the connect step; error paths that disconnect early and let queued async code post afterwards; worker scripts that post before connectToMainThread().","solutions":["Call session.connect() (or connectToMainThread() in a worker) immediately after constructing the Session, before the first post().","Route every post through a wrapper that checks your own connected flag, set in connect() and cleared in disconnect().","Cancel or drain pending callbacks before disconnecting so late posts are skipped."],"exampleFix":"// before\nconst session = new inspector.Session();\nsession.post('Runtime.enable'); // ERR_INSPECTOR_NOT_CONNECTED\n\n// after\nconst session = new inspector.Session();\nsession.connect();\nsession.post('Runtime.enable');","handlingStrategy":"validation","validationCode":"import { Session } from 'node:inspector';\nclass SafeSession {\n  #s = new Session();\n  #connected = false;\n  connect() { this.#s.connect(); this.#connected = true; }\n  disconnect() { this.#s.disconnect(); this.#connected = false; }\n  post(method, params, cb) {\n    if (!this.#connected) throw new Error('inspector session not connected');\n    this.#s.post(method, params, cb);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  session.post('Runtime.enable');\n} catch (e) {\n  if (e.code === 'ERR_INSPECTOR_NOT_CONNECTED') {\n    session.connect();\n    session.post('Runtime.enable');\n  } else throw e;\n}","preventionTips":["Connect immediately after constructing the Session; disconnect only at final teardown.","Never post from timers or callbacks that may outlive disconnect().","Centralize session lifecycle in one module so ordering is obvious."],"tags":["inspector","session","protocol","node-compat"],"backgroundTag":"inspector-session-state","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}