paperclipai/paperclip · warning · RunnerGoalActionError

session_goals_unsupported

session_goals_unsupported

Error message

session_goals_unsupported: Session goals are unsupported.

What it means

Before accepting a goal action, `act` checks `initialProjection.capability.availability !== "available"` and throws `RunnerGoalActionError` with the capability's reasonCode, defaulting to `session_goals_unsupported`. This means the agent's adapter/session does not support session goals at all (or not right now).

Source

Thrown at server/src/services/runner-goals.ts:366

    };
  }

  async function act(
    companyId: string,
    issueId: string,
    request: RunnerGoalActionRequest,
  ): Promise<RunnerGoalActionAccepted> {
    const binding = await readBinding(companyId, issueId, request.agentId);
    if (!binding) throw new RunnerGoalActionError("issue_not_found", "Issue not found.");
    if (!binding.agent) throw new RunnerGoalActionError("agent_not_found", "Agent not found.");
    if (binding.issue.assigneeAgentId !== request.agentId) {
      throw new RunnerGoalActionError("agent_not_assigned", "The selected agent is not assigned to this issue.");
    }
    const fallbackCapability = capabilityForAgent(binding.agent);
    const initialProjection = await projection(companyId, issueId, request.agentId);
    if (!initialProjection) throw new RunnerGoalActionError("issue_not_found", "Issue not found.");
    if (initialProjection.capability.availability !== "available") {
      throw new RunnerGoalActionError(
        initialProjection.capability.reasonCode ?? "session_goals_unsupported",
        initialProjection.capability.reason ?? "Session goals are unsupported.",
      );
    }

    const accepted = await db.transaction(async (tx) => {
      await tx.insert(agentTaskSessions).values({
        companyId,
        agentId: request.agentId,
        adapterType: binding.agent!.adapterType,
        taskKey: issueId,
      }).onConflictDoNothing();
      const [session] = await tx.select().from(agentTaskSessions).where(and(
        eq(agentTaskSessions.companyId, companyId),
        eq(agentTaskSessions.agentId, request.agentId),
        eq(agentTaskSessions.adapterType, binding.agent!.adapterType),
        eq(agentTaskSessions.taskKey, issueId),
      )).limit(1).for("update");

View on GitHub (pinned to 01ad858492)

Solutions

  1. Check the projection's `capability.reason`/`reasonCode` first — it explains the specific unsupported reason
  2. Only issue goal actions for agents/adapters that advertise session-goal capability (availability === 'available')
  3. Re-probe capabilities: restart or re-establish the agent session so capability detection can run
  4. Upgrade or fix the adapter implementation to support session goals

Example fix

// before
await runnerGoals.act(companyId, issueId, { agentId, action: 'set', goal: '...' });
// after
const proj = await runnerGoals.projection(companyId, issueId, agentId);
if (proj.capability.availability !== 'available') return; // read proj.capability.reason
await runnerGoals.act(companyId, issueId, { agentId, action: 'set', goal: '...' });
Defensive patterns

Strategy: fallback

Validate before calling

const proj = await runnerGoals.projection(companyId, issueId, agentId);
if (proj.capability.availability !== 'available') {
  return { skipped: true, reason: proj.capability.reason ?? 'session goals unsupported' };
}

Type guard

function goalsSupported(proj) {
  return proj?.capability?.availability === 'available';
}

Try / catch

try {
  await runnerGoals.act(companyId, issueId, req);
} catch (e) {
  if (e instanceof RunnerGoalActionError && e.code === 'session_goals_unsupported') {
    // degrade gracefully: skip goal management for this session
  } else throw e;
}

Prevention

When it happens

Trigger: Calling set/pause/resume/clear goal actions against an agent whose adapter capability is not `available` and whose reasonCode is unset; adapters that don't implement goal control (e.g. adapters without session-goal support) always hit this path.

Common situations: Using an adapter type that lacks goal support; adapter feature flags disabled; capability probing failed during session startup so reasonCode falls back to the default; agent upgraded/downgraded between adapter versions with differing goal support.

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


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/bd77df45484b2870. Report an issue: GitHub.