paperclipai/paperclip · error
Cloud runtime identity is already claimed by another asserti
Error message
Cloud runtime identity is already claimed by another assertion
What it means
Inside the apply transaction, if a persisted runtime identity row already exists and its stored assertion does not equal the incoming claims (assertionsEqual compares the canonical serialized fields), the instance is considered owned by a different assertion. This throw prevents a second, different assertion from hijacking an already-claimed instance.
Source
Thrown at server/src/services/cloud-runtime-identity.ts:389
if (!initialized) throw new Error("Cloud runtime identity provider is not initialized");
const claims = verifyCloudRuntimeIdentityAssertion({
compactJws: input.compactJws,
env,
now: input.now,
// After a natural restart the provider env may already be canonical, but
// an identical retry of the original claim is still safe and idempotent.
// The durable row preserves the pool origin that assertion had to match
// on first application.
expectedPreviousOrigin: currentIdentity?.previousOrigin ?? startupOrigin,
});
const previousOrigin = claims.previousOrigin;
const canonicalOrigin = claims.canonicalOrigin;
const row = await input.db.transaction(async (tx) => {
const existing = await readPersistedIdentity(tx);
if (existing) {
if (!assertionsEqual(existing, claims)) {
throw new Error("Cloud runtime identity is already claimed by another assertion");
}
return existing;
}
const now = input.now ?? new Date();
await tx
.insert(instanceSettings)
.values({
singletonKey: SINGLETON_KEY,
general: {
v: 1,
stackId: claims.sub,
claimId: claims.claimId,
previousOrigin,
canonicalOrigin,
stackSlug: claims.stackSlug,
},
experimental: {},View on GitHub (pinned to 01ad858492)
Solutions
- Replay the ORIGINAL assertion exactly (it is idempotent and returns the existing row)
- If a new identity is genuinely required, clear/release the persisted runtime identity through the intended re-claim/teardown flow, then apply the new assertion
- Verify you are not pointing a second runtime at another runtime's database
- Compare the persisted assertion with the incoming one to confirm which fields differ
Example fix
// before
await applyCloudRuntimeIdentityAssertion({ db, compactJws: newlyMintedJws }); // new keypair
// after
await applyCloudRuntimeIdentityAssertion({ db, compactJws: originalJws }); // identical retry is idempotent Defensive patterns
Strategy: try-catch
Validate before calling
const existing = await readPersistedIdentity(db);
if (existing) {
const incoming = decodeJwtPayload(jws);
if (incoming.sub !== existing.stackId || incoming.claimId !== existing.claimId) {
throw new Error('instance already claimed; replay original assertion or release first');
}
} Try / catch
try {
await applyCloudRuntimeIdentityAssertion({ db, compactJws: jws });
} catch (e) {
if (e.message.includes('already claimed by another assertion')) {
// Not retryable with this jws: fetch/release existing claim or use the original assertion
throw new ClaimConflictError(e);
}
throw e;
} Prevention
- Persist and replay the original assertion verbatim; application is idempotent for identical retries
- Use the official release/teardown flow before claiming with a new identity
- Ensure one runtime owns one instance database
- Alert on any attempt to claim an already-claimed instance — it usually means a provisioning bug
When it happens
Trigger: applyCloudRuntimeIdentityAssertion called with a compactJws whose claims differ from the persisted identity row: re-claiming with a new claimId, new keypair, or changed origins after the instance was already claimed.
Common situations: Rebuilding/replacing the runtime without clearing the instance's persisted identity; key rotation minting a new assertion for an already-claimed instance; pointing two runtimes at the same instance DB; retrying with a regenerated assertion after a partial failure.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- No auth user has a non-empty credential account, instance-ad
- No auth user has an instance-admin role and active company m
- ${options.errorLabel} decision predicate failed: ${detail}
- ${options.errorLabel} decision predicate exited 0 (expected
- ${label} had drifted migration history; repaired migration j
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/86813763ddfe7224.
Report an issue: GitHub.