paperclipai/paperclip · error · Error
${prefix}: "captureCredential" must be a function when prese
Error message
${prefix}: "captureCredential" must be a function when present. What it means
Thrown by assertValidAdapterLoginCapability when the OPTIONAL member captureCredential is present but is not a function. captureCredential(output: string) => Buffer | null is only set by flows that print the minted credential to the terminal; the validator allows the field to be absent, but a present non-function value (boolean, string, object) means the capability shape is malformed.
Source
Thrown at packages/adapter-utils/src/login-capability.ts:142
}
if (!isOneOf(ADAPTER_LOGIN_SANDBOX_TRANSPORTS, cap.sandboxTransport)) {
throw new Error(
`${prefix}: "sandboxTransport" must be one of ${ADAPTER_LOGIN_SANDBOX_TRANSPORTS.join(", ")}.`,
);
}
if (!isOneOf(ADAPTER_LOGIN_TIMEOUT_POLICIES, cap.timeoutPolicy)) {
throw new Error(
`${prefix}: "timeoutPolicy" must be one of ${ADAPTER_LOGIN_TIMEOUT_POLICIES.join(", ")}.`,
);
}
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.View on GitHub (pinned to a7e689b3c3)
Solutions
- Remove the captureCredential field entirely if the login flow never prints the credential to the terminal.
- Or provide a function (output: string) => Buffer | null that returns the raw credential bytes when present in the output, else null.
- Never store the credential in the capability object itself; the function returns a runtime secret, the capability data must not.
- Type the capability as AdapterLoginCapability so `captureCredential: true` fails to compile.
Example fix
// before
loginCapability = { ..., captureCredential: true };
// after
loginCapability = { ... };
// or, when the CLI prints the token:
// captureCredential: (output) => /^token: (\S+)$/m.exec(output)?.[1] ? Buffer.from(/^token: (\S+)$/m.exec(output)![1]) : null, Defensive patterns
Strategy: type-guard
Validate before calling
const cap = capability as { captureCredential?: unknown };
const ok = cap.captureCredential === undefined || typeof cap.captureCredential === "function"; Type guard
import type { AdapterLoginCapability } from "@paperclipai/adapter-utils";
function captureCredentialOk(v: unknown): v is AdapterLoginCapability {
const c = v as { captureCredential?: unknown };
return c.captureCredential === undefined || typeof c.captureCredential === "function";
} Try / catch
try {
assertValidAdapterLoginCapability(cap, adapterType);
} catch (error) {
throw new Error(`optional member captureCredential malformed: ${String(error)}`);
} Prevention
- Optional means omit it, not flag it with true/false.
- The function returns Buffer | null and must never leak credentials into logs.
- Prefer omitting captureCredential unless the CLI prints the credential to the terminal.
When it happens
Trigger: An adapter sets captureCredential: true (feature flag style), captureCredential: "auto", or a config object, instead of a function; validateAdapterLoginCapability throws at load time.
Common situations: Using the field as an on/off flag because other tools use booleans for optional capabilities; serializing a capability that once held a function (functions become undefined/null in JSON, but hand-written fixtures may hold junk); misunderstanding optional-vs-flag semantics.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 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/bdd02249517e0ab5.
Report an issue: GitHub.