{"record":{"id":"b95f8cddf4fc86e8","repo":"paperclipai/paperclip","slug":"session-goals-are-unsupported-by-this-agent","errorCode":null,"errorMessage":"Session goals are unsupported by this agent.","messagePattern":"Session goals are unsupported by this agent\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/src/components/task-chat/RunnerGoalWidget.tsx","lineNumber":100,"sourceCode":"    if (current && next.revision > current.revision + 1) {\n      void query.refetch();\n      return;\n    }\n    if (!current || next.revision >= current.revision) queryClient.setQueryData(key, next);\n  });\n\n  const executeAction = useCallback(async (\n    action: RunnerGoalAction,\n    objective?: string,\n    confirmReplace = false,\n    expectedRevision?: number,\n  ) => {\n    setActionError(null);\n    try {\n      const current = query.data ?? (await query.refetch()).data;\n      if (!current?.agentId) throw new Error(current?.capability.reason ?? \"Select an agent to use /goal.\");\n      if (current.capability.availability !== \"available\") {\n        throw new Error(current.capability.reason ?? \"Session goals are unsupported by this agent.\");\n      }\n      await mutation.mutateAsync({\n        requestId: requestId(),\n        agentId: current.agentId,\n        expectedRevision: expectedRevision ?? current.revision,\n        action,\n        ...(objective ? { objective } : {}),\n        ...(action === \"replace\" ? { confirmReplace } : {}),\n      });\n    } catch (error) {\n      setActionError(error instanceof Error ? error.message : \"The goal action could not be applied.\");\n      throw error;\n    }\n  }, [mutation, query]);\n\n  const edit = useCallback(async () => {\n    const current = query.data ?? (await query.refetch()).data;\n    if (!current?.goal) throw new Error(\"There is no current session goal to edit.\");","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/ui/src/components/task-chat/RunnerGoalWidget.tsx#L82-L118","documentation":"In the same useRunnerGoalControl action handler, once a runner has an agentId the code checks capability.availability. If it is anything other than \"available\", the goal action is rejected with the backend's capability.reason, falling back to the static message \"Session goals are unsupported by this agent.\" This prevents issuing goals to agents/runners that do not implement session goals.","triggerScenarios":"Invoking a goal action while the capability query reports availability !== \"available\" (e.g. \"unsupported\" or \"unavailable\") and no specific capability.reason is provided — typically an adapter/agent that lacks session-goal support.","commonSituations":"Using /goal with an agent adapter that has not implemented session goals; a temporarily unavailable runner marking capability as unavailable; older adapter versions predating goal support; stale capability data that a refetch would correct.","solutions":["Use an agent/adapter that supports session goals; switch the runner's agent if needed.","Refetch the capability query — transient \"unavailable\" states resolve after the runner is healthy.","Read capability.reason in the API response for the specific blocker when supplied.","Upgrade the agent adapter to a version with session-goal support.","Skip the goal UI for agents whose capability reports unsupported, so users see it disabled upfront."],"exampleFix":"// before: blindly rendering the goal widget\n<RunnerGoalWidget runnerId={id} />\n\n// after: gate on capability\n{capability?.availability === \"available\" ? (\n  <RunnerGoalWidget runnerId={id} />\n) : (\n  <span>Goals unsupported for this agent</span>\n)}","handlingStrategy":"validation","validationCode":"const cap = useRunnerGoalCapabilityQuery(runnerId).data;\nconst goalsSupported = cap?.agentId != null && cap?.capability?.availability === \"available\";\nif (!goalsSupported) disableGoalWidget(cap?.capability?.reason ?? \"Session goals are unsupported by this agent.\");","typeGuard":"const goalsAvailable = (cap: { capability: { availability: string } } | null | undefined): boolean =>\n  cap?.capability?.availability === \"available\";","tryCatchPattern":"try {\n  await runnerGoal.control({ action, goal });\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"unsupported by this agent\")) {\n    showNotice(\"This agent does not support session goals.\");\n  } else throw e;\n}","preventionTips":["Gate the goal UI on capability.availability === \"available\" before rendering.","Surface capability.reason to users instead of the generic fallback.","Prefer agents/adapters with session-goal support when goals are required.","Refetch capability after runner restarts so transient states clear."],"tags":["ui","react-query","goal","capability-check"],"backgroundTag":"unsupported-operation","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"}