{"record":{"id":"2f494982de6895f6","repo":"Mintplex-Labs/anything-llm","slug":"agent-not-running","errorCode":null,"errorMessage":"agent not running","messagePattern":"agent not running","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"open-computer/services/interface-service/routes/api.js","lineNumber":438,"sourceCode":"        }\n        console.log(`[pi] ${isLoop ? \"Loop\" : \"Idle\"} response: ${response || \"(dismissed)\"}`);\n        return res.json({ status: \"ok\" });\n      }\n\n      const responseRpc = workspace.pendingHelp.rpc || workspace.piRpc;\n      if (responseRpc) {\n        responseRpc.write(\n          JSON.stringify({\n            type: \"extension_ui_response\",\n            id: requestId,\n            value: response || \"\",\n          }) + \"\\n\",\n        );\n        workspace.pendingHelp = null;\n        console.log(`[pi] Help response sent: ${response}`);\n        return res.json({ status: \"ok\" });\n      }\n      return res.status(500).json({ error: \"agent not running\" });\n    }\n\n    return res.status(404).json({ error: \"no pending help request with that id\" });\n  });\n\n  // ── Headless root ──────────────────────────────────────────────────────\n\n  app.get(\"/\", (req, res, next) => {\n    if (!HEADLESS) return next();\n    res.json({\n      service: \"interface-service\",\n      agent: AGENT_NAME,\n      status: \"ok\",\n      agent_status: currentAgentStatus(),\n      headless: true,\n      uptime_seconds: Math.floor(process.uptime()),\n      platform: process.platform,\n      arch: process.arch,","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/open-computer/services/interface-service/routes/api.js#L420-L456","documentation":"Returned (HTTP 500) by POST /api/v1/help-response in the interface-service when the requestId matches the current workspace.pendingHelp, but both workspace.pendingHelp.rpc and workspace.piRpc are null. The response cannot be delivered because the RPC stream that would carry the extension_ui_response JSON message to the agent process is gone. The service nulls workspace.piRpc when the agent session ends or the process dies (api.js:380), but pendingHelp can survive that reset, so a matched id still 500s.","triggerScenarios":"POST /api/v1/help-response with body {requestId, response} where requestId === workspace.pendingHelp.id, the id does NOT start with 'idle-' or 'loop-' (those take the nudge branch), and the pi agent process has crashed, exited, or was restarted via POST /api/v1/session/new so that workspace.piRpc is null and pendingHelp.rpc is unset.","commonSituations":"Agent OOM-killed or container restarted between asking for help and the user answering; a new session started (clears piRpc at api.js:380) while the help dialog was still open in the UI; headless deployment where the pi child process died silently; extension RPC disconnected before the user clicked submit.","solutions":["Restart or reconnect the agent (or POST /api/v1/session/new) so workspace.piRpc is re-established, then re-send the help response","Check the agent status via GET / (headless root exposes agent_status) or the service logs to learn why the process died","If the pending question is stale, start a new session and prompt the agent again instead of replaying the old requestId","Service authors: also clear workspace.pendingHelp wherever piRpc drops to null, so stale dialogs return the 404 instead of a 500"],"exampleFix":"// before\nconst res = await fetch(`${BASE}/api/v1/help-response`, {\n  method: 'POST', headers: {'Content-Type': 'application/json'},\n  body: JSON.stringify({requestId, response}),\n});\n\n// after: verify the agent is alive, and restart before retrying\nconst status = await (await fetch(`${BASE}/`)).json();\nif (status.agent_status !== 'running')\n  await fetch(`${BASE}/api/v1/session/new`, {method: 'POST'});\nconst res = await fetch(`${BASE}/api/v1/help-response`, {\n  method: 'POST', headers: {'Content-Type': 'application/json'},\n  body: JSON.stringify({requestId, response}),\n});\nif (res.status === 500) {\n  const {error} = await res.json();\n  if (error === 'agent not running') { /* re-ask the agent; this dialog is undeliverable */ }\n}","handlingStrategy":"retry","validationCode":"const status = await (await fetch(`${BASE}/`)).json(); // headless root returns agent_status\nif (status.agent_status !== 'running') {\n  await fetch(`${BASE}/api/v1/session/new`, {method: 'POST'}); // re-establish workspace.piRpc\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(`${BASE}/api/v1/help-response`, opts);\n  if (!res.ok) {\n    const body = await res.json().catch(() => ({}));\n    if (res.status === 500 && body.error === 'agent not running') {\n      await restartAgentSession(); // then let the agent re-ask; do not loop on the stale id\n    }\n  }\n} catch (e) {\n  // network-level failure reaching the interface-service itself\n}","preventionTips":["Poll GET / for agent_status before submitting help responses in long-lived UIs","Auto-dismiss open help dialogs when the agent disconnects or a new session starts","Watch for session-reset broadcasts that null piRpc and pendingHelp together"],"tags":["agent-lifecycle","rpc","http-500","interface-service","help-request"],"backgroundTag":"service-unavailable","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}