{"record":{"id":"43e80e5fcc829db3","repo":"paperclipai/paperclip","slug":"run-context-mismatch","errorCode":"run_context_mismatch","errorMessage":"Supplied run context does not match stored heartbeat context","messagePattern":"Supplied run context does not match stored heartbeat context","errorType":"http","errorClass":"ToolGatewayHttpError","httpStatus":403,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":1511,"sourceCode":"        403,\n        \"Run does not belong to agent\",\n        \"run_agent_mismatch\",\n      );\n    }\n    if (!ACTIVE_GATEWAY_RUN_STATUSES.has(run.status)) {\n      throw new ToolGatewayHttpError(403, \"Run is not active\", \"run_inactive\");\n    }\n\n    const snapshot = asRecord(run.contextSnapshot);\n    const snapshotIssueId = stringValue(snapshot?.issueId);\n    const snapshotProjectId = stringValue(snapshot?.projectId);\n    if (\n      (input.issueId && snapshotIssueId && input.issueId !== snapshotIssueId) ||\n      (input.projectId &&\n        snapshotProjectId &&\n        input.projectId !== snapshotProjectId)\n    ) {\n      throw new ToolGatewayHttpError(\n        403,\n        \"Supplied run context does not match stored heartbeat context\",\n        \"run_context_mismatch\",\n      );\n    }\n    const issueId = snapshotIssueId ?? input.issueId ?? null;\n    let projectId = snapshotProjectId ?? input.projectId ?? null;\n    if (issueId) {\n      const [issue] = await db\n        .select({ companyId: issues.companyId, projectId: issues.projectId })\n        .from(issues)\n        .where(eq(issues.id, issueId))\n        .limit(1);\n      if (!issue || issue.companyId !== input.companyId) {\n        throw new ToolGatewayHttpError(\n          403,\n          \"Issue context is outside the run company\",\n          \"run_context_mismatch\",","sourceCodeStart":1493,"sourceCodeEnd":1529,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/tool-gateway.ts#L1493-L1529","documentation":"Guard in the tool gateway run-context check: the companyId/agentId supplied with the gateway request do not match the heartbeat run stored for that runId, or the run is not in an active gateway status. It fires when a client reuses a runId belonging to a different company/agent or after the run finished, protecting against cross-tenant or stale-session tool execution.","triggerScenarios":"Thrown at server/src/services/tool-gateway.ts:1077 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Supply the same run context (runId, etc.) that was stored at heartbeat/session creation; do not mix contexts from different runs."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}