paperclipai/paperclip · error · RunnerGoalActionError

agent_not_found

agent_not_found

Error message

agent_not_found: Agent not found.

What it means

`act` also validates the agent. If the issue exists but the requested agentId does not resolve to an agent on the binding (readBinding returned a binding whose agent is undefined), it throws RunnerGoalActionError with code 'agent_not_found'. Note this is distinct from agent_not_assigned, which fires when the agent exists but is not the issue's assignee.

Source

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

      sessionId: session?.id ?? null,
      capability: storedCapability(session, capabilityForAgent(binding.agent)),
      goal,
      workingNow: goal?.workingNow ?? false,
      activeRunId: activeRun?.id ?? null,
      pendingAction: projectedPendingAction,
      revision: session?.goalRevision ?? 0,
      observedAt: session?.goalObservedAt?.toISOString() ?? null,
    };
  }

  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,

View on GitHub (pinned to 01ad858492)

Solutions

  1. List agents for the companyId and confirm the agentId exists before acting
  2. Use the issue's current assigneeAgentId when the intent is to act as the assignee
  3. Update stale configs/clients that reference deleted agent ids
  4. Distinguish the failure: agent_not_found means bad id, agent_not_assigned means wrong-but-existing agent — fix the request accordingly

Example fix

// before: acting with a hardcoded agent id
const request = { agentId: 'agent_legacy_1', ... };
await act(companyId, issueId, request);
// after: resolve a live agent id
const agent = await getAgent(companyId, issue.assigneeAgentId);
const request = { agentId: agent.id, ... };
await act(companyId, issueId, request);
Defensive patterns

Strategy: try-catch

Validate before calling

const agents = await listAgents(companyId);
if (!agents.some(a => a.id === request.agentId)) {
  throw new Error(`Agent ${request.agentId} not found in company ${companyId}`);
}

Try / catch

try {
  await act(companyId, issueId, request);
} catch (e) {
  if (e instanceof RunnerGoalActionError && e.code === 'agent_not_found') {
    // resolve a live agentId (e.g. issue.assigneeAgentId) and retry
  } else if (e instanceof RunnerGoalActionError && e.code === 'agent_not_assigned') {
    // agent exists but is not the assignee; fix the request
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the runner-goal action with an agentId that does not exist within the company — deleted agent, id from another company, wrong id field passed (e.g. adapter id instead of agent id), or the agent record was removed after the binding snapshot.

Common situations: Agent was deleted/rotated while a client still held its id; mixing up agent vs assignment vs user ids; cross-company ids due to shared tooling; stale configuration referencing a removed agent.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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