{"record":{"id":"20fcfd21da2bfea4","repo":"paperclipai/paperclip","slug":"goal-not-found-20fcfd","errorCode":"goal_not_found","errorMessage":"goal_not_found: There is no current session goal.","messagePattern":"goal_not_found: There is no current session goal\\.","errorType":"error_code","errorClass":"RunnerGoalActionError","httpStatus":null,"severity":"warning","filePath":"server/src/services/runner-goals.ts","lineNumber":440,"sourceCode":"            ? \"clear\"\n            : \"set\";\n      if (capability.availability !== \"available\" || !capability.actions.includes(requiredCapabilityAction)) {\n        throw new RunnerGoalActionError(\n          capability.reasonCode ?? \"goal_action_unsupported\",\n          capability.reason ?? `${request.action} is unsupported by this agent session.`,\n        );\n      }\n      if (request.tokenBudget != null && !capability.tokenBudgetControl) {\n        throw new RunnerGoalActionError(\n          \"goal_token_budget_unsupported\",\n          \"This agent session does not support goal token budgets.\",\n        );\n      }\n      if (request.action === \"create\" && currentGoal && currentGoal.status !== \"complete\") {\n        throw new RunnerGoalConflictError(\"replacement_required\", currentProjection);\n      }\n      if ([\"edit\", \"replace\", \"pause\", \"resume\", \"clear\"].includes(request.action) && !currentGoal) {\n        throw new RunnerGoalActionError(\"goal_not_found\", \"There is no current session goal.\");\n      }\n\n      const nextRevision = session.goalRevision + 1;\n      const desiredState = request.action === \"pause\"\n        ? \"paused\"\n        : request.action === \"clear\"\n          ? null\n          : \"active\";\n      await tx.update(agentTaskSessions).set({\n        goalDesiredState: desiredState,\n        goalRevision: nextRevision,\n        updatedAt: new Date(),\n      }).where(eq(agentTaskSessions.id, session.id));\n      const pendingProjection: RunnerGoalProjection = {\n        ...currentProjection,\n        pendingAction: pendingAction(request.action),\n        revision: nextRevision,\n      };","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/runner-goals.ts#L422-L458","documentation":"Goal mutations edit/replace/pause/resume/clear require an existing current goal. When `storedGoal(session)` returns null (no goal was ever set, or it was cleared), `act` throws `goal_not_found`. Only 'create' is valid on a goalless session.","triggerScenarios":"Calling pause/resume/clear/edit/replace when the session has no goal; pausing after the goal auto-completed and was cleared; scripts replaying pause/resume after a session restart that lost the goal.","commonSituations":"UI buttons enabled without checking currentGoal; race where another actor cleared the goal first; assuming the goal from a previous session persists; goal completed and pruned before a resume arrives.","solutions":["Check the projection's `currentGoal` before mutating; skip or create if null","Use action 'create' when no goal exists instead of edit/replace/pause/resume/clear","Refresh the projection after conflicts and adapt the action to the actual goal state","Make pause/resume automation idempotent: treat goal_not_found as a no-op"],"exampleFix":"// before\nawait act(companyId, issueId, { agentId, action: 'pause', ... });\n// after\nconst proj = await projection(companyId, issueId, agentId);\nif (!proj.currentGoal) return; // nothing to pause\nawait act(companyId, issueId, { agentId, action: 'pause', ... });","handlingStrategy":"type-guard","validationCode":"const proj = await runnerGoals.projection(companyId, issueId, agentId);\nif (!proj.currentGoal) return { skipped: true, reason: 'no current goal' };","typeGuard":"function hasActiveGoal(proj) {\n  return proj?.currentGoal != null;\n}","tryCatchPattern":"try {\n  await runnerGoals.act(companyId, issueId, req);\n} catch (e) {\n  if (e instanceof RunnerGoalActionError && e.code === 'goal_not_found') {\n    // treat as no-op or create a goal first\n    return await runnerGoals.act(companyId, issueId, { ...req, action: 'create', goal: defaultGoal });\n  }\n  throw e;\n}","preventionTips":["Gate edit/replace/pause/resume/clear on currentGoal != null","Make pause/resume automations tolerant of a missing goal","Re-read the projection after clears/completions before further actions","Enable goal controls only when a goal is present"],"tags":["not-found","goal","state"],"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-14T05:17:10.506Z"}