paperclipai/paperclip · error · Error
request.runnerd.sha256 must be a SHA-256 digest
Error message
request.runnerd.sha256 must be a SHA-256 digest
What it means
The runnerd section of an eval-session request identifies the runner daemon build by SHA-256 digest. parseEvalSessionRequest validates request.runnerd.sha256 with /^(?:sha256:)?[a-f0-9]{64}$/i and throws when the value is missing, not a string, or does not look like a 64-character hex digest (an optional "sha256:" prefix is allowed).
Source
Thrown at packages/paperclip-runner/src/cli/eval-session-contract.ts:283
}
if (provider !== "aws_agentcore" && agentCoreProfileInput !== undefined) {
throw new Error("eval-session agentCoreProfile requires provider aws_agentcore");
}
if (input.nativeResume !== undefined) {
throw new Error(
"eval-session nativeResume requires a retained live-session checkpoint",
);
}
if (input.includeCollaborationModeInstructions === false) {
throw new Error(
"current CapabilityLiveSessionService requires collaboration-mode instructions",
);
}
const runnerd = object(input.runnerd, "request.runnerd");
const digest = text(runnerd.sha256, "request.runnerd.sha256");
if (!/^(?:sha256:)?[a-f0-9]{64}$/i.test(digest)) {
throw new Error("request.runnerd.sha256 must be a SHA-256 digest");
}
const limits = object(input.limits, "request.limits");
const sessionInput = object(input.session, "request.session");
const session = sessionInput as unknown as CreateCapabilityLiveSessionInput;
const model = text(input.model, "request.model");
if (provider === "claude_managed" && model !== "claude-sonnet-5") {
throw new Error("Claude Managed evals require exact model claude-sonnet-5");
}
if (
provider === "aws_agentcore" &&
model !== "global.anthropic.claude-sonnet-4-6"
) {
throw new Error(
"AWS AgentCore evals require exact model global.anthropic.claude-sonnet-4-6",
);
}
if (sessionInput.provider !== undefined && sessionInput.provider !== provider) {
throw new Error("request.session.provider must match request.provider");View on GitHub (pinned to 01ad858492)
Solutions
- Populate request.runnerd.sha256 with the runner daemon's actual SHA-256 content digest (64 hex chars, optionally prefixed with "sha256:").
- Compute it correctly, e.g. `sha256sum <runnerd-artifact> | awk '{print $1}'`, and verify length is 64.
- Fix the request builder so runnerd.sha256 is never emitted empty or as a placeholder.
Example fix
// before
"runnerd": { "sha256": "a1b2c3" }
// after
"runnerd": { "sha256": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" } Defensive patterns
Strategy: validation
Validate before calling
const SHA256_RE = /^(?:sha256:)?[a-f0-9]{64}$/i;
if (!SHA256_RE.test(req.runnerd?.sha256 ?? "")) throw new Error("runnerd.sha256 must be a 64-hex SHA-256 digest"); Type guard
function isValidRunnerdDigest(input) { return typeof input?.runnerd?.sha256 === "string" && /^(?:sha256:)?[a-f0-9]{64}$/i.test(input.runnerd.sha256); } Try / catch
try { return parseEvalSessionRequest(raw); } catch (e) { if (String(e.message).includes("must be a SHA-256 digest")) { throw new Error(`Bad runnerd.sha256: ${JSON.stringify(raw?.runnerd?.sha256)}; compute with sha256sum of the runnerd artifact`); } throw e; } Prevention
- Compute the digest from the actual runnerd artifact, never hand-write it.
- Validate digests with the same regex before sending.
- Distinguish Git commit SHAs from SHA-256 content digests in build tooling.
When it happens
Trigger: Calling parseEvalSessionRequest with runnerd absent, runnerd.sha256 absent, or a sha256 value such as "abc123", a full Git SHA of wrong length, an uppercase non-hex string, or a digest with whitespace/newlines.
Common situations: Passing a Git commit hash (often not exactly 64 hex chars) instead of a sha256 content digest; emitting a truncated or placeholder digest in generated configs; a version upgrade changing the digest format; forgetting to populate runnerd when hand-writing the request.
Related errors
- current CapabilityLiveSessionService requires collaboration-
- eval-session agentCoreProfile requires provider aws_agentcor
- Invalid status '${String(rawStatus)}'. Must be one of: ${PLU
- "tool" is required and must be a string
- "runContext" is required and must be an object
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-02).
Data as JSON: /api/errors/7206e9fda0b97972.
Report an issue: GitHub.