{"record":{"id":"0c056b9ec3e003a0","repo":"paperclipai/paperclip","slug":"workflow-eval-run-input-runid-is-missing","errorCode":null,"errorMessage":"workflow eval run ${input.runId} is missing","messagePattern":"workflow eval run (.+?) is missing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/eval/live-workflow-executor.ts","lineNumber":155,"sourceCode":"async function completeWorkflowRun(\n  adapter: CapabilityMockControlPlaneAdapter,\n  input: {\n    runId: string;\n    sessionId: string;\n    source: string;\n    disposition: \"done\" | \"blocked\";\n    summary: string;\n  },\n): Promise<void> {\n  const terminal: PrpTerminalState = {\n    schema: \"paperclip.prp.terminal.v1\",\n    turnTerminalState: \"completed\",\n    runTerminalState: \"succeeded\",\n    reportedWorkDisposition: input.disposition,\n  };\n  const current = adapter.snapshot().runs.find((run) => run.id === input.runId);\n  if (current === undefined) {\n    throw new Error(`workflow eval run ${input.runId} is missing`);\n  }\n  if (current.result !== null) return;\n  if (\n    !current.events.some(\n      (event) => \"eventType\" in event && event.eventType === \"run.terminal\",\n    )\n  ) {\n    await adapter.appendEvent({\n      schema: \"paperclip.prp.event.v1\",\n      sourceEventId: `${input.source}:terminal:1`,\n      sourceSeq: 1,\n      sourceInstanceId: input.source,\n      sourceKind: \"runner\",\n      runId: input.runId,\n      normalizedSessionId: input.sessionId,\n      turnId: `${input.source}-turn`,\n      eventType: \"run.terminal\",\n      schemaVersion: 1,","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/eval/live-workflow-executor.ts#L137-L173","documentation":"completeWorkflowRun in the live workflow executor looks up the run identified by input.runId in the eval adapter's snapshot of runs. When no run with that id exists in the adapter snapshot, it throws this error instead of silently completing. The check guards against completing results for runs that were never started or were already discarded.","triggerScenarios":"Calling completeWorkflowRun (directly or via advanceDelegationReturnMockState) with a runId that was never registered on the adapter, a runId from a previous executor instance, or one whose snapshot was reset before completion.","commonSituations":"Stale runId persisted from an earlier eval session; typos or id drift between the matrix definition and the executor; re-running an eval against a fresh adapter without re-creating runs; concurrency where a run was removed between scheduling and completion.","solutions":["Log the adapter.snapshot().runs ids and confirm input.runId matches one of them.","Re-create or re-register the run before calling completeWorkflowRun.","Ensure the same adapter instance that started the run is used to complete it.","If the run is legitimately gone, treat completion as a no-op instead of throwing (check existence first)."],"exampleFix":"// before\nawait executor.completeWorkflowRun({ runId: staleRunId, disposition: 'completed' });\n// after\nconst exists = adapter.snapshot().runs.some((r) => r.id === staleRunId);\nif (exists) await executor.completeWorkflowRun({ runId: staleRunId, disposition: 'completed' });","handlingStrategy":"try-catch","validationCode":"const runExists = adapter.snapshot().runs.some((r) => r.id === input.runId);\nif (!runExists) throw new Error(`refusing to complete unknown run ${input.runId}`);","typeGuard":"function runIsKnown(adapter: EvalAdapter, runId: string): boolean {\n  return adapter.snapshot().runs.some((r) => r.id === runId);\n}","tryCatchPattern":"try {\n  await executor.completeWorkflowRun(input);\n} catch (err) {\n  if ((err as Error).message === `workflow eval run ${input.runId} is missing`) {\n    logger.warn({ runId: input.runId }, 'run vanished before completion; skipping');\n    return;\n  }\n  throw err;\n}","preventionTips":["Use the same adapter instance for scheduling and completing runs.","Persist runIds together with the adapter/session identity so stale ids are detectable.","Log snapshot run ids on mismatch to speed up diagnosis.","Reset runIds whenever the executor or adapter is recreated."],"tags":["eval","state","not-found","workflow"],"backgroundTag":"record-not-found","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"}