{"record":{"id":"6c1b0ef9e2734bb0","repo":"paperclipai/paperclip","slug":"session-unavailable","errorCode":"session_unavailable","errorMessage":"session_unavailable: Agent task session is unavailable.","messagePattern":"session_unavailable: Agent task session is unavailable\\.","errorType":"error_code","errorClass":"RunnerGoalActionError","httpStatus":null,"severity":"error","filePath":"server/src/services/runner-goals.ts","lineNumber":385,"sourceCode":"        initialProjection.capability.reasonCode ?? \"session_goals_unsupported\",\n        initialProjection.capability.reason ?? \"Session goals are unsupported.\",\n      );\n    }\n\n    const accepted = await db.transaction(async (tx) => {\n      await tx.insert(agentTaskSessions).values({\n        companyId,\n        agentId: request.agentId,\n        adapterType: binding.agent!.adapterType,\n        taskKey: issueId,\n      }).onConflictDoNothing();\n      const [session] = await tx.select().from(agentTaskSessions).where(and(\n        eq(agentTaskSessions.companyId, companyId),\n        eq(agentTaskSessions.agentId, request.agentId),\n        eq(agentTaskSessions.adapterType, binding.agent!.adapterType),\n        eq(agentTaskSessions.taskKey, issueId),\n      )).limit(1).for(\"update\");\n      if (!session) throw new RunnerGoalActionError(\"session_unavailable\", \"Agent task session is unavailable.\");\n\n      const currentGoal = storedGoal(session);\n      const currentProjection: RunnerGoalProjection = {\n        ...initialProjection,\n        sessionId: session.id,\n        capability: storedCapability(session, fallbackCapability),\n        goal: currentGoal,\n        workingNow: currentGoal?.workingNow ?? false,\n        revision: session.goalRevision,\n        observedAt: session.goalObservedAt?.toISOString() ?? null,\n      };\n\n      const [existingAction] = await tx.select().from(agentSessionGoalActions).where(and(\n        eq(agentSessionGoalActions.sessionId, session.id),\n        eq(agentSessionGoalActions.requestId, request.requestId),\n      )).limit(1);\n      if (existingAction) {\n        if (!isSameGoalActionRequest(existingAction.payloadJson, request)) {","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/runner-goals.ts#L367-L403","documentation":"Inside the transactional block of `act`, the code selects an `agentTaskSessions` row keyed by (companyId, agentId, adapterType, taskKey=issueId) FOR UPDATE. If no session row exists it throws `session_unavailable`. A goal action requires a live agent task session to attach to; goals cannot exist sessionless.","triggerScenarios":"Calling a goal action when no agent task session has been started for that issue/agent; the session was terminated or cleaned up before the action; adapterType mismatch between the stored agent and session rows so the WHERE clause misses; issueId not matching session.taskKey.","commonSituations":"Runner retries goal actions after session teardown; agent crashed and its session was reaped; calling goals before the agent has started working on the issue (session not yet created); reassignment changed adapterType.","solutions":["Start an agent task session for the issue first (let the agent check out/start work), then send goal actions","Re-check session existence via the sessions API before calling `act`","If the session died, restart the agent run and re-establish the session before managing goals","Verify the agentId and adapterType in your request match the session that was actually created"],"exampleFix":"// before\nawait runnerGoals.act(companyId, issueId, { agentId, action: 'pause' }); // session may not exist\n// after\nconst sessions = await listAgentTaskSessions(companyId, agentId, issueId);\nif (sessions.length === 0) await startAgentTask(companyId, issueId, agentId);\nawait runnerGoals.act(companyId, issueId, { agentId, action: 'pause' });","handlingStrategy":"validation","validationCode":"const sessions = await listAgentTaskSessions(companyId, { agentId, taskKey: issueId });\nif (sessions.length === 0) throw new Error('no agent task session for this issue');","typeGuard":"function hasSession(sessions) {\n  return Array.isArray(sessions) && sessions.length > 0;\n}","tryCatchPattern":"try {\n  await runnerGoals.act(companyId, issueId, req);\n} catch (e) {\n  if (e instanceof RunnerGoalActionError && e.code === 'session_unavailable') {\n    await startAgentTask(companyId, issueId, req.agentId); // then retry\n  } else throw e;\n}","preventionTips":["Ensure the agent started the task (session exists) before goal actions","Re-verify session existence after agent restarts or crashes","Match agentId/adapterType exactly with the created session","Treat session teardown as invalidating pending goal actions"],"tags":["session","state","not-found"],"backgroundTag":"resource-not-found","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"}