paperclipai/paperclip · error · Error
${prefix}: "completionClaim" must be one of ${ADAPTER_LOGIN_
Error message
${prefix}: "completionClaim" must be one of ${ADAPTER_LOGIN_COMPLETION_CLAIMS.join(", ")} when present. What it means
Thrown by assertValidAdapterLoginCapability when the OPTIONAL member completionClaim is present but not one of the fixed claims (currently only "storedSessionId"). The claim tells the login flow what to record on success; any other string is a malformed capability and the loader fails closed.
Source
Thrown at packages/adapter-utils/src/login-capability.ts:151
);
}
if (typeof cap.getCommand !== "function") {
throw new Error(`${prefix}: "getCommand" must be a function.`);
}
if (typeof cap.parsePrompt !== "function") {
throw new Error(`${prefix}: "parsePrompt" must be a function.`);
}
if (cap.captureCredential !== undefined && typeof cap.captureCredential !== "function") {
throw new Error(`${prefix}: "captureCredential" must be a function when present.`);
}
if (cap.onComplete !== undefined && typeof cap.onComplete !== "function") {
throw new Error(`${prefix}: "onComplete" must be a function when present.`);
}
if (
cap.completionClaim !== undefined &&
!isOneOf(ADAPTER_LOGIN_COMPLETION_CLAIMS, cap.completionClaim)
) {
throw new Error(
`${prefix}: "completionClaim" must be one of ${ADAPTER_LOGIN_COMPLETION_CLAIMS.join(", ")} when present.`,
);
}
}
/**
* Validates the optional login capability of an adapter module. The function is
* a no-op when the module declares no login capability. It throws a clear error
* when the module declares a malformed capability, so the loader fails closed.
*/
export function validateAdapterLoginCapability(mod: {
type?: unknown;
loginCapability?: unknown;
}): void {
if (mod.loginCapability === undefined) return;
const adapterType = typeof mod.type === "string" && mod.type.length > 0 ? mod.type : "unknown";
assertValidAdapterLoginCapability(mod.loginCapability, adapterType);
}View on GitHub (pinned to a7e689b3c3)
Solutions
- Use completionClaim: "storedSessionId" when the flow stores a session identifier on success.
- Omit completionClaim entirely if the flow records nothing.
- If you genuinely need a new claim, add it to ADAPTER_LOGIN_COMPLETION_CLAIMS in @paperclipai/adapter-utils (and the AdapterLoginCompletionClaim type) first, then use it.
- Type the field as AdapterLoginCompletionClaim for compile-time checking.
Example fix
// before
loginCapability = { ..., completionClaim: "session-id" };
// after
loginCapability = { ..., completionClaim: "storedSessionId" }; Defensive patterns
Strategy: type-guard
Validate before calling
import { ADAPTER_LOGIN_COMPLETION_CLAIMS } from "@paperclipai/adapter-utils";
const c = capability as { completionClaim?: unknown };
const ok = c.completionClaim === undefined ||
(ADAPTER_LOGIN_COMPLETION_CLAIMS as readonly string[]).includes(c.completionClaim as string); Type guard
import { ADAPTER_LOGIN_COMPLETION_CLAIMS, type AdapterLoginCapability } from "@paperclipai/adapter-utils";
function completionClaimOk(v: unknown): v is AdapterLoginCapability {
const c = v as { completionClaim?: unknown };
return c.completionClaim === undefined ||
(ADAPTER_LOGIN_COMPLETION_CLAIMS as readonly string[]).includes(c.completionClaim as string);
} Try / catch
try {
assertValidAdapterLoginCapability(cap, adapterType);
} catch (error) {
throw new Error(`completionClaim invalid: ${String(error)}`);
} Prevention
- Only "storedSessionId" exists today; omit the field rather than inventing claims.
- Extending the claim set means changing adapter-utils first, then the adapter.
- Type the field as AdapterLoginCompletionClaim.
When it happens
Trigger: An adapter sets completionClaim: "session_id", "apiKey", "stored_session_id" (spelling variant), or a non-string; validateAdapterLoginCapability throws during module load.
Common situations: Authors inventing claim names to match their vendor vocabulary; adding a new claim in the adapter before the constant ADAPTER_LOGIN_COMPLETION_CLAIMS in adapter-utils supports it; leaving a placeholder string from a template.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- ${prefix}: "panelMode" must be one of ${ADAPTER_LOGIN_PANEL_
- ${prefix}: "sandboxTransport" must be one of ${ADAPTER_LOGIN
- ${prefix}: "timeoutPolicy" must be one of ${ADAPTER_LOGIN_TI
- ${prefix}: "getCommand" must be a function.
- ${prefix}: "parsePrompt" must be a function.
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-21).
Data as JSON: /api/errors/26377d5c2a954cf1.
Report an issue: GitHub.