{"record":{"id":"ba0922dd82dd7ff7","repo":"paperclipai/paperclip","slug":"goal-action-unsupported","errorCode":"goal_action_unsupported","errorMessage":"goal_action_unsupported: ${request.action} is unsupported by this agent session.","messagePattern":"goal_action_unsupported: (.+?) is unsupported by this agent session\\.","errorType":"error_code","errorClass":"RunnerGoalActionError","httpStatus":null,"severity":"warning","filePath":"server/src/services/runner-goals.ts","lineNumber":425,"sourceCode":"          repeated: true,\n          session,\n          status: existingAction.status,\n          result: asRecord(existingAction.resultJson),\n        };\n      }\n      if (session.goalRevision !== request.expectedRevision) {\n        throw new RunnerGoalConflictError(\"stale_revision\", currentProjection);\n      }\n      const capability = storedCapability(session, fallbackCapability);\n      const requiredCapabilityAction = request.action === \"pause\"\n        ? \"pause\"\n        : request.action === \"resume\"\n          ? \"resume\"\n          : request.action === \"clear\"\n            ? \"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;","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/runner-goals.ts#L407-L443","documentation":"After loading the session's stored capability, `act` requires `capability.availability === 'available'` and that `capability.actions` includes the action implied by the request (set/edit/replace→set, pause→pause, resume→resume, clear→clear). Otherwise it throws `RunnerGoalActionError` with the capability's reasonCode, defaulting to `goal_action_unsupported`. The session exists but doesn't permit this specific goal operation.","triggerScenarios":"Calling pause/resume/clear on an agent whose capability.actions list only includes 'set'; calling any goal action on a session whose stored capability degraded to unavailable; adapter sessions that support goal setting but not pausing.","commonSituations":"Capability narrowed after session start (agent adapter negotiated fewer actions); UI offers all goal buttons regardless of capability; adapter version differences in supported actions; session capability probe failed and reasonCode defaults.","solutions":["Read the projection's `capability.actions` array and only send actions it includes","Surface only the supported goal controls in UI/tooling per session capability","Re-establish the session to re-negotiate full capability if actions are unexpectedly limited","Read `capability.reason`/`reasonCode` in the error to learn the adapter-specific cause"],"exampleFix":"// before\nawait act(companyId, issueId, { agentId, action: 'pause', ... });\n// after\nconst proj = await projection(companyId, issueId, agentId);\nif (!proj.capability.actions.includes('pause')) return; // pause not supported\nawait act(companyId, issueId, { agentId, action: 'pause', ... });","handlingStrategy":"validation","validationCode":"const proj = await runnerGoals.projection(companyId, issueId, agentId);\nif (proj.capability.availability !== 'available' || !proj.capability.actions.includes(action)) {\n  return { skipped: true, reason: proj.capability.reason ?? 'action unsupported' };\n}","typeGuard":"function actionSupported(proj, action) {\n  return proj?.capability?.availability === 'available' && proj.capability.actions.includes(action);\n}","tryCatchPattern":"try {\n  await runnerGoals.act(companyId, issueId, req);\n} catch (e) {\n  if (e instanceof RunnerGoalActionError && e.code === 'goal_action_unsupported') {\n    // hide/disable the control or fall back to supported actions\n  } else throw e;\n}","preventionTips":["Drive goal UI from capability.actions, not a static action list","Re-read capability after session changes","Fall back to supported actions (e.g. replace instead of pause)","Surface capability.reason to operators"],"tags":["capability","unsupported","adapter"],"backgroundTag":"unsupported-operation","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"}