paperclipai/paperclip · critical
Persisted Cloud runtime identity contains an invalid stack s
Error message
Persisted Cloud runtime identity contains an invalid stack slug
What it means
The persisted Cloud runtime identity must satisfy two slug invariants: stackSlug matches STACK_SLUG_PATTERN (lowercase alphanumeric/hyphens, 2-63 chars, starts and ends alphanumeric), and the first label of canonicalOrigin's hostname equals the stackSlug. This binds the durable claim's slug to the actual DNS name the instance is served from. If either check fails at startup, this error is thrown.
Source
Thrown at server/src/services/cloud-runtime-identity.ts:166
return [];
}
})();
env.PAPERCLIP_RUNTIME_API_CANDIDATES_JSON = JSON.stringify([
identity.canonicalOrigin,
...existingCandidates.filter((candidate) => candidate !== identity.canonicalOrigin),
]);
}
function assertPersistedIdentityMatchesStack(row: PersistedRuntimeIdentity, env: NodeJS.ProcessEnv) {
const configuredStackId = nonEmpty(env.PAPERCLIP_CLOUD_STACK_ID);
if (!configuredStackId || configuredStackId !== row.stackId) {
throw new Error("Persisted Cloud runtime identity does not match PAPERCLIP_CLOUD_STACK_ID");
}
if (!exactHttpsOrigin(row.previousOrigin) || !exactHttpsOrigin(row.canonicalOrigin)) {
throw new Error("Persisted Cloud runtime identity contains an invalid origin");
}
if (!STACK_SLUG_PATTERN.test(row.stackSlug) || new URL(row.canonicalOrigin).hostname.split(".")[0] !== row.stackSlug) {
throw new Error("Persisted Cloud runtime identity contains an invalid stack slug");
}
}
/** Load the durable claim before auth, routes, and child-runtime configuration. */
export async function initializeCloudRuntimeIdentity(
db: Db,
env: NodeJS.ProcessEnv = process.env,
): Promise<CloudRuntimeIdentitySnapshot | null> {
startupOrigin = configuredStartupOrigin(env);
// Self-hosted servers have no Cloud stack identity to restore. Avoid touching
// the singleton table on that path; besides keeping the feature inert, this
// preserves lightweight startup/test database seams that intentionally do
// not construct a database client.
if (!nonEmpty(env.PAPERCLIP_CLOUD_STACK_ID)) {
initialized = true;
currentIdentity = null;
return null;
}View on GitHub (pinned to 01ad858492)
Solutions
- Make canonicalOrigin's hostname first label equal stackSlug — either fix the persisted canonicalOrigin to the correct '<slug>.<domain>' URL or correct the stackSlug in the instance_settings row (singletonKey 'cloud-runtime-identity/v1').
- If the deployment's hostname legitimately changed (stack renamed), the clean path is a fresh instance claim for the new hostname rather than editing the old row, since the claim is one-time.
- Check the slug against the pattern ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$ before writing it via any custom migration.
Example fix
// persisted row // before (slug/hostname mismatch) stackSlug: "my-stack", canonicalOrigin: "https://wrong-name.example.com" // after stackSlug: "my-stack", canonicalOrigin: "https://my-stack.example.com"
Defensive patterns
Strategy: validation
Validate before calling
const STACK_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
function slugMatchesOrigin(slug: string, canonicalOrigin: string): boolean {
try {
return STACK_SLUG_PATTERN.test(slug) &&
new URL(canonicalOrigin).hostname.split(".")[0] === slug;
} catch { return false; }
}
// before writing or deploying:
if (!slugMatchesOrigin(stackSlug, canonicalOrigin)) throw new Error("stackSlug must be the first DNS label of canonicalOrigin"); Type guard
function isValidIdentityPair(row: { stackSlug: string; canonicalOrigin: string }): boolean {
try {
return /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(row.stackSlug) &&
new URL(row.canonicalOrigin).hostname.split(".")[0] === row.stackSlug;
} catch { return false; }
} Prevention
- Always provision the hostname as '<stackSlug>.<domain>' so slug and DNS label agree
- When renaming a stack or its hostname, re-run the identity claim instead of editing the persisted row
- Validate slugs against the pattern before persisting them in custom tooling
- Include the slug/origin pair in deploy-time smoke checks
When it happens
Trigger: initializeCloudRuntimeIdentity loads a persisted identity where row.stackSlug fails STACK_SLUG_PATTERN (uppercase, underscores, leading/trailing hyphen, too long, or empty), or new URL(row.canonicalOrigin).hostname.split('.')[0] !== row.stackSlug (e.g. slug 'my-stack' but origin 'https://other.example.com').
Common situations: A Cloud deployment renamed the stack or its DNS hostname without re-claiming identity, so the persisted slug and origin no longer agree; a hand-edited or incorrectly migrated instance_settings row; a database restored from a different stack whose hostname prefix differs; a slug containing invalid characters was written by custom tooling.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Persisted Cloud runtime identity does not match PAPERCLIP_CL
- Persisted Cloud runtime identity contains an invalid origin
- ACPX runtime omitted acpxRecordId
- ACPX runtime omitted backendSessionId
- Cloud runtime identity destination is invalid
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/d4c3967cfaa4f695.
Report an issue: GitHub.