paperclipai/paperclip · error · Error
Evalbook attempt identity is empty
Error message
Evalbook attempt identity is empty
What it means
safeSegment normalizes an Evalbook attempt identity (e.g. attempt ID or candidate name) into a safe path segment and throws when the sanitized result is empty. The error means the identity input was empty, whitespace-only, or consisted entirely of characters stripped by the sanitizer.
Source
Thrown at packages/paperclip-runner/scripts/render-runner-workflow-evalbook.mjs:22
import { resolve } from "node:path";
const EVAL_PROGRAM_RELATIVE_PATH =
"evals/paperclip-runner/tools/eval_program.py";
function json(value) {
return `${JSON.stringify(value, null, 2)}\n`;
}
function sha256(value) {
return createHash("sha256").update(value).digest("hex");
}
function safeSegment(value) {
const segment = String(value)
.trim()
.replaceAll(/[^0-9A-Za-z._-]+/g, "-")
.replaceAll(/^-+|-+$/g, "");
if (!segment) throw new Error("Evalbook attempt identity is empty");
return segment;
}
function candidateDescriptor(report, candidateId) {
const descriptor =
report.bundle.providerVersions?.[candidateId] ?? candidateId;
const separator = descriptor.indexOf(":");
return separator < 0
? { driver: "unknown driver", model: descriptor }
: {
driver: descriptor.slice(0, separator),
model: descriptor.slice(separator + 1),
};
}
function scoreChecks(result) {
const dimensionChecks = Object.values(result.scorecard.dimensions).map(
(dimension) => ({View on GitHub (pinned to 01ad858492)
Solutions
- Ensure the attempt/candidate identifier is a non-empty meaningful value before rendering
- Log the raw value passed to safeSegment to see what sanitized to empty
- Fix the upstream report so the identity field is populated
- If ids can legitimately be blank, provide a default like 'unknown-attempt' at the call site
Example fix
// before safeSegment(report.attemptId); // '' // after safeSegment(report.attemptId || 'unknown-attempt');
Defensive patterns
Strategy: validation
Validate before calling
if (!String(value ?? '').trim()) throw new Error('Attempt identity is empty'); Type guard
const hasIdentity = (v) => typeof v === 'string' && v.trim().length > 0;
Try / catch
try { const seg = safeSegment(id); } catch (e) { if (e.message.includes('identity is empty')) console.error('Attempt id was:', JSON.stringify(id)); throw e; } Prevention
- Validate upstream report fields before rendering
- Provide sensible defaults for optional identity fields
- Log raw identifiers when building attempt paths
When it happens
Trigger: Passing an attempt id like '///', '---', or '' (undefined coerces to 'undefined' so usually passes); a candidate id that is only spaces or symbols.
Common situations: A workflow report with a missing/blank attempt field; upstream data change where the identifier field was renamed and now reads undefined-but-coerced or stripped-clean to nothing; manual runs passing a placeholder value.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- 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
- "runContext" must include agentId, runId, companyId, and pro
- ${prefix}: the capability must be an object.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/c261f2ba42a39324.
Report an issue: GitHub.