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

  1. Replay the ORIGINAL assertion exactly (it is idempotent and returns the existing row)
  2. 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
  3. Verify you are not pointing a second runtime at another runtime's database
  4. 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

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


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