paperclipai/paperclip · error
${options.errorLabel} decision predicate failed: ${detail}
Error message
${options.errorLabel} decision predicate failed: ${detail} What it means
decideGrokAuthMerge runs a child `node` predicate (grok-auth-merge-decision.cjs) that must exit 10, 20, 21, or 22. If the process fails to spawn, crashes with another exit code, or errors, the wrapper throws this labeled error so a broken predicate is never silently treated as a merge decision. The message embeds the underlying detail (spawn failure, unexpected exit code, or error message).
Source
Thrown at packages/adapters/grok-local/src/server/grok-auth-merge-decision.ts:70
destinationPath: string,
options: DecideGrokAuthMergeOptions,
): Promise<number> {
try {
await execFile("node", [DECISION_SCRIPT_PATH, sourcePath, destinationPath]);
} catch (error) {
const code = (error as { code?: unknown }).code;
if (typeof code === "number" && KNOWN_EXIT_CODES.has(code)) {
return code;
}
const detail =
typeof code === "string"
? `node could not be executed (${code})`
: typeof code === "number"
? `unexpected predicate exit code ${code}`
: error instanceof Error
? error.message
: String(error);
throw new Error(`${options.errorLabel} decision predicate failed: ${detail}`);
}
// `execFile` resolved, so the predicate exited 0. The predicate always
// exits 10, 20, 21, or 22, so a clean exit 0 is unexpected; fail loud.
throw new Error(
`${options.errorLabel} decision predicate exited 0 (expected 10, 20, 21, or 22)`,
);
}
View on GitHub (pinned to 5716fe907e)
Solutions
- Confirm `node --version` works in the same environment the server runs in; install node or fix PATH.
- Verify grok-auth-merge-decision.cjs exists next to the compiled module (check your build/bundling step).
- Run the predicate manually: `node grok-auth-merge-decision.cjs <src> <dst>; echo $?` to see the real crash.
- Fix the source/destination paths passed in if the predicate is crashing on file access.
Example fix
// before: spawn fails because node is missing in the packaged app
await execFile("node", [script, src, dst]);
// after: resolve an explicit runtime and verify availability first
const nodeBin = process.env.NODE_BIN ?? "node";
await execFile(nodeBin, [script, src, dst]); // and ship the .cjs with the bundle Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: node exists and the predicate script is present
import { accessSync, constants } from "node:fs";
try { accessSync(DECISION_SCRIPT_PATH, constants.X_OK); } catch { throw new Error("decision predicate missing: " + DECISION_SCRIPT_PATH); }
await execFile("node", ["--version"]); // throws ENOENT if node is unavailable Type guard
function isSpawnError(e: unknown): e is NodeJS.ErrnoException {
return e instanceof Error && typeof (e as NodeJS.ErrnoException).code === "string";
} Try / catch
try {
const code = await decideGrokAuthMerge(src, dst, { errorLabel: "grok auth copy-out" });
} catch (e) {
if (e instanceof Error && e.message.includes("decision predicate failed")) {
// never assume "keep destination" — a broken predicate is a hard failure
log.error(e.message); // includes node spawn error or unexpected exit code
}
throw e;
} Prevention
- Ship grok-auth-merge-decision.cjs with your build/bundle and verify it post-install.
- Ensure node is on PATH in the runtime (containers, packaged apps).
- Never edit the predicate without keeping its exit-code contract (10/20/21/22).
- Smoke-test the predicate on fixture files at startup.
When it happens
Trigger: `node` is not on PATH or not executable (code is a string like ENOENT/EACCES); the predicate script crashed with an exit code outside {10,20,21,22} (e.g. uncaught exception → exit 1); the .cjs file is missing from the build output.
Common situations: Deploying/packaging without copying grok-auth-merge-decision.cjs; running in an environment without node in PATH (bundled/electron runtime); corrupted source/destination paths causing the predicate to throw; syntax error in a locally patched predicate.
Related errors
- ${options.errorLabel} decision predicate exited 0 (expected
- Workspace database repair command timed out during ${repairP
- Workspace database repair command failed during ${repairPhas
- PAPERCLIP_BRIDGE_TOKEN is required.
- No auth user has a non-empty credential account, instance-ad
AI-assisted analysis of paperclipai/paperclip@5716fe907e (2026-09-02).
Data as JSON: /api/errors/a4f0ef8ae51ad686.
Report an issue: GitHub.