{"record":{"id":"5cf671cbaa1a45a2","repo":"paperclipai/paperclip","slug":"stop-sandbox-callback-bridge-timed-out-detail","errorCode":null,"errorMessage":"stop sandbox callback bridge timed out${detail ? `: ${detail}` : \"\"}","messagePattern":"stop sandbox callback bridge timed out(.+?)` : \"\"\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/sandbox-callback-bridge.ts","lineNumber":1150,"sourceCode":"            `  pid=\"$(cat ${shellQuote(directories.pidFile)})\"`,\n            \"  kill \\\"$pid\\\" 2>/dev/null || true\",\n            \"  i=0\",\n            \"  while kill -0 \\\"$pid\\\" 2>/dev/null && [ \\\"$i\\\" -lt 40 ]; do\",\n            \"    i=$((i + 1))\",\n            \"    sleep 0.05\",\n            \"  done\",\n            \"fi\",\n            `rm -f ${shellQuote(directories.pidFile)} ${shellQuote(directories.readyFile)}`,\n          ].join(\"\\n\"),\n        ),\n        cwd: input.remoteCwd,\n        env: {\n          [SANDBOX_EXEC_CHANNEL_ENV]: SANDBOX_EXEC_CHANNEL_BRIDGE,\n        },\n        timeoutMs,\n      });\n      if (stopResult.timedOut) {\n        throw new Error(buildRunnerFailureMessage(\"stop sandbox callback bridge\", stopResult));\n      }\n    },\n  };\n}\n\nfunction getSandboxCallbackBridgeServerSource(): string {\n  return `import { randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\n\nconst queueDir = process.env.PAPERCLIP_BRIDGE_QUEUE_DIR;\nconst bridgeToken = process.env.PAPERCLIP_BRIDGE_TOKEN;\nconst host = process.env.PAPERCLIP_BRIDGE_HOST || \"127.0.0.1\";\nconst port = Number(process.env.PAPERCLIP_BRIDGE_PORT || \"0\");\nconst pollIntervalMs = Number(process.env.PAPERCLIP_BRIDGE_POLL_INTERVAL_MS || \"100\");\nconst responseTimeoutMs = Number(process.env.PAPERCLIP_BRIDGE_RESPONSE_TIMEOUT_MS || \"30000\");\nconst maxQueueDepth = Number(process.env.PAPERCLIP_BRIDGE_MAX_QUEUE_DEPTH || \"${DEFAULT_BRIDGE_MAX_QUEUE_DEPTH}\");","sourceCodeStart":1132,"sourceCodeEnd":1168,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/sandbox-callback-bridge.ts#L1132-L1168","documentation":"Thrown by the `stop` callback of a started sandbox callback bridge when the kill-and-wait command ran longer than timeoutMs. The stop routine sends SIGTERM to the recorded pid, polls up to 40 times (≈2s) for the process to exit, then removes pid/ready files; if the whole execute() call reports timedOut, this error fires. It signals the remote bridge process did not die within the configured shutdown budget.","triggerScenarios":"Calling the returned `stop()` function (bridge teardown at run end) where the remote shell execute timed out. Happens when the bridge node process ignores SIGTERM, the pidFile points at a zombie/reused pid, or the remote exec channel itself is stalled so even `kill` does not return.","commonSituations":"Bridge server has an open long-lived connection keeping the event loop alive; pid was recycled and now belongs to an unrelated process; remote host is under heavy load so the 40-iteration wait never sees exit; an earlier start left a stale pidFile pointing at a live process.","solutions":["Increase the timeoutMs passed to startSandboxCallbackBridge so teardown has more headroom.","Check whether the bridge node process is genuinely gone on the remote host after the error (ps for the pid from directories.pidFile).","Ensure the bridge server closes its HTTP server and pending connections on SIGTERM (review getSandboxCallbackBridgeServerSource signal handling).","Clean stale pidFile/readyFile from directories before a fresh start to avoid pid reuse confusion."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await bridge.stop();\n} catch (err) {\n  // Log and continue; the run is ending. Optionally attempt a forceful SIGKILL.\n  logger.warn('bridge stop failed/timed out', { error: (err as Error).message });\n}","preventionTips":["Size timeoutMs for teardown based on observed bridge shutdown time.","Ensure the bridge server closes HTTP connections and stops listening on SIGTERM.","Clean stale pidFile/readyFile before each start to avoid pid-reuse confusion."],"tags":["sandbox","bridge","timeout","teardown","remote-execution"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}