{"record":{"id":"901ed07686b4e2bc","repo":"paperclipai/paperclip","slug":"runner-goal-live-controller-unavailable","errorCode":"runner_goal_live_controller_unavailable","errorMessage":"runner_goal_live_controller_unavailable: The live agent goal controller is unavailable; the run was not interrupted.","messagePattern":"runner_goal_live_controller_unavailable: The live agent goal controller is unavailable; the run was not interrupted\\.","errorType":"error_code","errorClass":"RunnerGoalActionError","httpStatus":null,"severity":"error","filePath":"server/src/services/runner-goals.ts","lineNumber":983,"sourceCode":"      \"The live agent goal cannot be stopped safely.\",\n    );\n  }\n\n  const requestId = `interrupt_${randomUUID()}`;\n  const adapterControl = dispatchLiveRunnerGoalControl(binding, { requestId, action });\n  const nativeControl = adapterControl\n    ? null\n    : queueLiveRunnerPrpCommand({\n        ...binding,\n        type: action === \"pause\" ? \"session.goal.set\" : \"session.goal.clear\",\n        payload: action === \"pause\"\n          ? { requestId, status: \"paused\" }\n          : { requestId },\n        commandId: `goal_${requestId}`,\n      });\n  const completion = adapterControl?.completion ?? nativeControl?.completion ?? null;\n  if (!completion) {\n    throw new RunnerGoalActionError(\n      \"runner_goal_live_controller_unavailable\",\n      \"The live agent goal controller is unavailable; the run was not interrupted.\",\n    );\n  }\n  await completion;\n\n  const deadline = Date.now() + 5_000;\n  while (Date.now() < deadline) {\n    const observed = await goals.projection(binding.companyId, binding.issueId, binding.agentId);\n    if (action === \"pause\" && observed?.goal?.status === \"paused\") return \"paused\";\n    if (action === \"clear\" && observed?.goal === null) return \"cleared\";\n    await new Promise<void>((resolve) => setTimeout(resolve, 25));\n  }\n  throw new RunnerGoalActionError(\n    \"runner_goal_stop_unconfirmed\",\n    \"The provider did not confirm that the live agent goal stopped.\",\n  );\n}","sourceCodeStart":965,"sourceCodeEnd":1001,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/runner-goals.ts#L965-L1001","documentation":"settleLiveRunnerGoalBeforeInterrupt throws RunnerGoalActionError(runner_goal_live_controller_unavailable) when it decided a pause/clear action is required, but neither the live adapter control dispatch nor the queued PRP command returned a completion promise. The stop command could not be handed to any controller, so the run was definitively NOT interrupted — the failure is reported instead of leaving an unknown state.","triggerScenarios":"dispatchLiveRunnerGoalControl(binding, {requestId, action}) returns null (no live adapter controller attached to the session) AND queueLiveRunnerPrpCommand(...) also returns null (offline/queued command path unavailable), so adapterControl?.completion ?? nativeControl?.completion is null.","commonSituations":"Interrupting a run after the adapter process/connection died so no live controller is registered; a service restart dropped the in-flight controller registration; the PRP command queue rejects or drops the command (e.g. session no longer tracked); calling the stop path for a session that was never bound to a live controller.","solutions":["Verify the agent adapter session is still alive and registered with dispatchLiveRunnerGoalControl before calling the interrupt path.","Check logs for controller deregistration (process exit, reconnect) around the failure time and re-attach/restart the session.","Ensure the PRP offline command queue (queueLiveRunnerPrpCommand) is accepting commands for this session; fix queue unavailability.","Retry settleLiveRunnerGoalBeforeInterrupt once the session controller is re-established; the run was not interrupted so no cleanup is needed."],"exampleFix":"// before: call stop immediately after process restart\nawait settleLiveRunnerGoalBeforeInterrupt(db, binding);\n// after: ensure a controller exists first\nconst controller = getLiveController(binding);\nif (!controller) await restartAgentSession(binding); // re-register live controller\nawait settleLiveRunnerGoalBeforeInterrupt(db, binding);","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["adapter","control-plane","session"],"backgroundTag":"resource-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"}