{"record":{"id":"8ad3d9f899c488e3","repo":"paperclipai/paperclip","slug":"runnerd-exited-before-provider-turn-startup","errorCode":null,"errorMessage":"runnerd exited before provider turn startup","messagePattern":"runnerd exited before provider turn startup","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/live/runnerd-codex-transport.ts","lineNumber":5383,"sourceCode":"      // the new response fence. ACPX echoes the requested identity, while\n      // Codex and OpenCode return their provider-assigned identity.\n      const deadline =\n        this.options.turnStartTimeoutMs === undefined\n          ? Date.now() + 30_000\n          : commandDeadline;\n      const providerTurnStarted = () =>\n        turnStartResponseReady({\n          responseEpoch,\n          observedEpoch: this.#observedTurnStartEpoch,\n          expectedProviderTurnId,\n          boundTurnId: this.#turnId,\n        });\n      while (!providerTurnStarted() && Date.now() < deadline) {\n        this.#throwIfFailed();\n        this.#pumpEvents();\n        if (providerTurnStarted()) break;\n        if (await this.#runnerHasExited())\n          throw new Error(\"runnerd exited before provider turn startup\");\n        await new Promise((resolveWait) => setTimeout(resolveWait, 10));\n      }\n      if (!providerTurnStarted())\n        throw new Error(\"runnerd did not report the provider turn identity\");\n      responseReady = true;\n      return { turn: { id: this.#turnId, status: \"inProgress\" } };\n    } finally {\n      if (!responseReady) {\n        resolveAdmission(false);\n        if (this.#turnStartResponseEpoch === responseEpoch) {\n          this.#turnStartResponsePending = false;\n          this.#expectedProviderTurnId = null;\n        }\n      } else {\n        // Resolving this async method schedules the strict driver's response\n        // continuation as a microtask. Keep terminal frames held until the\n        // following task so the driver can bind and emit turn.accepted first.\n        // The epoch prevents a late release from clearing a newer turn fence.","sourceCodeStart":5365,"sourceCodeEnd":5401,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/live/runnerd-codex-transport.ts#L5365-L5401","documentation":"Startup guard in the turn-start wait loop of the runnerd Codex transport: while polling for the provider's turnStart response (bounded by turnStartTimeoutMs or 30s), the runnerd child process exited before the provider confirmed turn startup. The failure is in the runner daemon process, not the turn request itself.","triggerScenarios":"Thrown at packages/paperclip-runner/src/live/runnerd-codex-transport.ts:5383 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check runnerd stderr/diagnostics for the crash reason during turn startup","Restart the runner transport; a crashed runnerd is not recoverable in place","Verify runnerd binary compatibility (arch/platform) if it exits immediately on every turn"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}