{"record":{"id":"37c2f554350d9025","repo":"paperclipai/paperclip","slug":"cloud-runtime-identity-stack-does-not-match-this-i","errorCode":null,"errorMessage":"Cloud runtime identity stack does not match this instance","messagePattern":"Cloud runtime identity stack does not match this instance","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/cloud-runtime-identity.ts","lineNumber":326,"sourceCode":"    || payload.exp - payload.iat > MAX_ASSERTION_LIFETIME_SECONDS\n  ) {\n    throw new Error(\"Cloud runtime identity assertion is expired or has an invalid lifetime\");\n  }\n  return payload as RuntimeIdentityClaims;\n}\n\n/** Verify that an assertion is signed for this exact, still-unclaimed instance. */\nexport function verifyCloudRuntimeIdentityAssertion(input: {\n  compactJws: string;\n  env?: NodeJS.ProcessEnv;\n  now?: Date;\n  expectedPreviousOrigin: string | null;\n}): RuntimeIdentityClaims {\n  const env = input.env ?? process.env;\n  const claims = verifyClaims({ compactJws: input.compactJws, env, now: input.now ?? new Date() });\n  const configuredStackId = nonEmpty(env.PAPERCLIP_CLOUD_STACK_ID);\n  if (!configuredStackId || claims.sub !== configuredStackId) {\n    throw new Error(\"Cloud runtime identity stack does not match this instance\");\n  }\n  const previousOrigin = exactHttpsOrigin(claims.previousOrigin);\n  const canonicalOrigin = exactHttpsOrigin(claims.canonicalOrigin);\n  if (!previousOrigin || !canonicalOrigin || previousOrigin !== input.expectedPreviousOrigin) {\n    throw new Error(\"Cloud runtime identity previous or canonical origin is invalid\");\n  }\n  if (\n    !STACK_SLUG_PATTERN.test(claims.stackSlug)\n    || new URL(canonicalOrigin).hostname.split(\".\")[0] !== claims.stackSlug\n    || claims.claimId.length > 256\n    || claims.claimId.trim() !== claims.claimId\n    || !claims.claimId\n  ) {\n    throw new Error(\"Cloud runtime identity destination is invalid\");\n  }\n  return claims;\n}\n","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/cloud-runtime-identity.ts#L308-L344","documentation":"verifyCloudRuntimeIdentityAssertion checks that the assertion's sub claim names the exact stack this instance belongs to (PAPERCLIP_CLOUD_STACK_ID). It throws when PAPERCLIP_CLOUD_STACK_ID is unset or when the assertion was minted for a different stack id, so a foreign runtime identity cannot claim this instance.","triggerScenarios":"applyCloudRuntimeIdentityAssertion or verifyAssertion called where env.PAPERCLIP_CLOUD_STACK_ID is empty/nonEmpty-false, or where claims.sub differs from the configured stack id (e.g. assertion minted for stack A delivered to an instance of stack B).","commonSituations":"PAPERCLIP_CLOUD_STACK_ID not set in the instance environment; copy-pasting an assertion between dev/staging/prod stacks; re-pointing an instance to a new stack without re-minting the assertion; stale container images with old stack env.","solutions":["Set PAPERCLIP_CLOUD_STACK_ID in the instance environment to the stack id the assertion was minted for","Re-mint the assertion with sub equal to this instance's stack id","Confirm the assertion delivery is targeting the correct instance/stack","Log claims.sub (server-side) and compare against env to diagnose mismatch"],"exampleFix":"// before\nPAPERCLIP_CLOUD_STACK_ID=   # unset\n// after\nPAPERCLIP_CLOUD_STACK_ID=stack_01hxyz   # matches assertion sub claim","handlingStrategy":"validation","validationCode":"const configured = process.env.PAPERCLIP_CLOUD_STACK_ID;\nconst sub = decodeJwtPayload(jws).sub;\nif (!configured || sub !== configured) throw new Error(`stack mismatch: sub=${sub} configured=${configured}`);","typeGuard":"function matchesStack(claims: {sub:string}, env: NodeJS.ProcessEnv): boolean {\n  return Boolean(env.PAPERCLIP_CLOUD_STACK_ID) && claims.sub === env.PAPERCLIP_CLOUD_STACK_ID;\n}","tryCatchPattern":"try {\n  await applyCloudRuntimeIdentityAssertion({ db, compactJws: jws });\n} catch (e) {\n  if (e.message.includes('stack does not match')) {\n    logger.error({ configured: process.env.PAPERCLIP_CLOUD_STACK_ID }, 'assertion minted for a different stack');\n  }\n  throw e;\n}","preventionTips":["Set PAPERCLIP_CLOUD_STACK_ID in every instance environment as part of provisioning","Never copy assertions between stacks; mint per-stack","Include stack id in deployment checks/health probes","Keep assertion delivery channels stack-scoped"],"tags":["auth","config","cloud"],"backgroundTag":"invalid-config-value","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"}