paperclipai/paperclip · error · RunnerGoalActionError
runner_goal_stop_unsupported
runner_goal_stop_unsupported
Error message
runner_goal_stop_unsupported: The live agent goal cannot be stopped safely.
What it means
settleLiveRunnerGoalBeforeInterrupt throws RunnerGoalActionError(runner_goal_stop_unsupported) when a live goal exists and is not complete/paused, but the provider capability list advertises neither the pause nor the clear action. Without one of those actions the service cannot safely stop the running goal before the agent process is interrupted, so it refuses rather than orphaning a live run.
Source
Thrown at server/src/services/runner-goals.ts:963
* session. Codex-style sessions pause; providers that only advertise clear
* (currently Claude ACP) are cleared. The caller must not interrupt the process
* until this function confirms the resulting projection.
*/
export async function settleLiveRunnerGoalBeforeInterrupt(
db: Db,
binding: { companyId: string; issueId: string; agentId: string },
): Promise<"paused" | "cleared" | "none"> {
const goals = runnerGoalService(db);
const current = await goals.projection(binding.companyId, binding.issueId, binding.agentId);
if (!current?.goal || current.goal.status === "complete") return "none";
if (current.goal.status === "paused") return "paused";
const action = current.capability.actions.includes("pause")
? "pause" as const
: current.capability.actions.includes("clear")
? "clear" as const
: null;
if (!action) {
throw new RunnerGoalActionError(
"runner_goal_stop_unsupported",
"The live agent goal cannot be stopped safely.",
);
}
const requestId = `interrupt_${randomUUID()}`;
const adapterControl = dispatchLiveRunnerGoalControl(binding, { requestId, action });
const nativeControl = adapterControl
? null
: queueLiveRunnerPrpCommand({
...binding,
type: action === "pause" ? "session.goal.set" : "session.goal.clear",
payload: action === "pause"
? { requestId, status: "paused" }
: { requestId },
commandId: `goal_${requestId}`,
});
const completion = adapterControl?.completion ?? nativeControl?.completion ?? null;View on GitHub (pinned to 01ad858492)
Solutions
- Upgrade or fix the adapter so its capability declaration includes "pause" or "clear" and the corresponding control handler is implemented.
- Check the adapter's reported capability (current.capability.actions) to confirm what stop actions the provider actually supports.
- Wait for the goal to reach "complete" or "paused" status before interrupting, since the stop path is skipped in those states.
- Use a different provider/adapter that supports live goal control if safe interruption is required.
Example fix
// before (capability without stop actions)
const capability = { actions: ["set"] };
// after
const capability = { actions: ["set", "pause", "clear"] }; // adapter must implement the pause/clear handler Defensive patterns
Strategy: try-catch
When it happens
Trigger: Calling settleLiveRunnerGoalBeforeInterrupt() for an issue whose current.capability.actions array contains neither "pause" nor "clear" while a non-complete, non-paused goal is active. This happens with adapters/providers that expose no goal-stop control surface.
Common situations: Using an agent adapter whose provider does not implement goal pause/clear (capability not yet implemented for that adapter type); a capability negotiation change after an adapter upgrade; calling the interrupt path on a session type that only supports implicit completion.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ${prefix}: the capability must be an object.
- session_goals_unsupported
- goal_action_unsupported
- runner_goal_live_controller_unavailable
- Adapter declares unsupported UI parser contract version — sk
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/0414674585754979.
Report an issue: GitHub.