{"record":{"id":"cf48b903358bb73b","repo":"paperclipai/paperclip","slug":"runnerd-did-not-report-the-provider-turn-identity","errorCode":null,"errorMessage":"runnerd did not report the provider turn identity","messagePattern":"runnerd did not report the provider turn identity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/live/runnerd-codex-transport.ts","lineNumber":5387,"sourceCode":"          ? 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.\n        const release = setTimeout(() => {\n          resolveAdmission(\n            !this.#closed && this.#turnStartResponseEpoch === responseEpoch,\n          );","sourceCodeStart":5369,"sourceCodeEnd":5405,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/live/runnerd-codex-transport.ts#L5369-L5405","documentation":"Thrown by the runnerd Codex transport's warm-start admission path after a polling loop that waits for runnerd to report the provider turn identity. The loop breaks early when `providerTurnStarted()` returns true, throws if the runner process has exited, and sleeps 10ms per iteration. If the loop exhausts without the identity being reported, the transport cannot safely return a `{ turn: { id, status: \"inProgress\" } }` result, so it aborts the turn start.","triggerScenarios":"Calling the transport's turn-start/startSession path while runnerd is slow to publish its provider turn identity (e.g. runnerd still booting, slow snapshot replay, or the identity event never emitted). Also occurs if `providerTurnStarted()`'s underlying evidence (provider identity event/state) never arrives before the poll deadline.","commonSituations":"Slow or overloaded machine running runnerd; a runnerd build that no longer emits the provider turn identity event; a hung codex subprocess; network/IPC stall between transport and runner; version skew between the transport and runnerd protocol.","solutions":["Check runnerd logs to see whether it started the provider turn at all; restart runnerd if it hung before emitting the identity.","Verify runnerd and the paperclip-runner package are version-matched so the provider turn identity event is emitted in the expected form.","Retry the turn start; transient startup slowness resolves on a fresh attempt.","If reproducible, capture the provider identity event stream and file a bug with the runnerd startup logs."],"exampleFix":"// before\nif (!providerTurnStarted())\n  throw new Error(\"runnerd did not report the provider turn identity\");\n// after\nif (!providerTurnStarted()) {\n  logger.warn(\"provider turn identity missing; retrying turn start\");\n  await restartRunnerd();\n  throw new Error(\"runnerd did not report the provider turn identity\");\n}","handlingStrategy":"retry","validationCode":"if (!transport.isProviderThreadReady()) await waitFor(() => transport.isProviderThreadReady(), { timeoutMs: 30_000 });","typeGuard":null,"tryCatchPattern":"try {\n  await transport.startTurn(input);\n} catch (err) {\n  if (err.message.includes(\"provider turn identity\")) {\n    await backoffRetry(() => transport.startTurn(input), 3);\n  } else throw err;\n}","preventionTips":["Keep runnerd and paperclip-runner versions matched.","Monitor runnerd startup latency and alert before the wait window is exceeded.","Avoid co-locating heavy workloads on the runner host that delay runnerd startup."],"tags":["runnerd","startup","timeout","ipc"],"backgroundTag":"request-timeout","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}