{"record":{"id":"cfdc14de4af1be9a","repo":"alibaba/page-agent","slug":"hub-is-not-connected-is-the-extension-running","errorCode":null,"errorMessage":"Hub is not connected. Is the extension running?","messagePattern":"Hub is not connected\\. Is the extension running\\?","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mcp/src/hub-bridge.js","lineNumber":85,"sourceCode":"\t\t\t})\n\t\t})\n\t}\n\n\tget connected() {\n\t\treturn this.#hub?.readyState === 1\n\t}\n\n\tget busy() {\n\t\treturn this.#pendingTask !== null\n\t}\n\n\t/**\n\t * @param {string} task\n\t * @param {Record<string, unknown>} [config]\n\t * @returns {Promise<{success: boolean, data: string}>}\n\t */\n\tasync executeTask(task, config) {\n\t\tif (!this.connected) throw new Error('Hub is not connected. Is the extension running?')\n\t\tif (this.#pendingTask) throw new Error('Agent is already running a task.')\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.#pendingTask = { resolve, reject }\n\t\t\tthis.#hub.send(JSON.stringify({ type: 'execute', task, config }))\n\t\t})\n\t}\n\n\tstopTask() {\n\t\tif (this.connected) {\n\t\t\tthis.#hub.send(JSON.stringify({ type: 'stop' }))\n\t\t}\n\t}\n\n\t// TODO: Add version checking\n\n\t/** @param {import('ws').WebSocket} ws */\n\t#onConnection(ws) {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/alibaba/page-agent/blob/d02db1ee7c41f5315beda88bab2fe935c580f662/packages/mcp/src/hub-bridge.js#L67-L103","documentation":"HubBridge.executeTask throws when the WebSocket connection to the browser extension hub is not open, i.e. this.connected is false. The bridge cannot send the task, so it fails immediately rather than queueing.","triggerScenarios":"Calling executeTask() before connect() resolves, after the WebSocket closed (extension reloaded, tab closed, network drop), or when the extension was never installed/enabled so connection never established.","commonSituations":"Extension updated/reloaded while the MCP server kept running; calling executeTask in a script right after constructing HubBridge without awaiting the connection handshake; extension not installed or the hub port not exposed; browser closed between tasks.","solutions":["Ensure the extension is installed and running, then re-establish the connection (await connect()) before executeTask","Track the close/disconnect event on the bridge and reconnect before dispatching the next task","Add a connectivity check (bridge.connected) before invoking and surface a actionable message to the user","Retry with backoff if the disconnect was transient (browser restarting)"],"exampleFix":"// before\nconst bridge = new HubBridge()\nbridge.connect()\nawait bridge.executeTask(task) // may run before handshake completes\n\n// after\nconst bridge = new HubBridge()\nawait bridge.connect() // wait for connection\nif (!bridge.connected) throw new Error('Extension not reachable — is it installed and enabled?')\nawait bridge.executeTask(task)","handlingStrategy":"validation","validationCode":"if (!bridge.connected) {\n  await bridge.connect()\n}\nif (!bridge.connected) {\n  throw new Error('Extension hub unreachable — install/enable the extension and retry')\n}","typeGuard":"null","tryCatchPattern":"try {\n  await bridge.executeTask(task)\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Hub is not connected')) {\n    await bridge.connect() // attempt reconnect once\n    return bridge.executeTask(task)\n  }\n  throw e\n}","preventionTips":["Always await connect() before executeTask","Listen for socket close and mark the bridge unusable; reconnect before next task","Handle extension reload events (chrome://extensions reload drops the socket)"],"tags":["websocket","extension","connection","mcp"],"backgroundTag":"websocket-not-connected","analyzedSha":"d02db1ee7c41f5315beda88bab2fe935c580f662","analyzedAt":"2026-08-28T19:39:48.634Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}