{"record":{"id":"c261f2ba42a39324","repo":"paperclipai/paperclip","slug":"evalbook-attempt-identity-is-empty","errorCode":null,"errorMessage":"Evalbook attempt identity is empty","messagePattern":"Evalbook attempt identity is empty","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/render-runner-workflow-evalbook.mjs","lineNumber":22,"sourceCode":"import { resolve } from \"node:path\";\n\nconst EVAL_PROGRAM_RELATIVE_PATH =\n  \"evals/paperclip-runner/tools/eval_program.py\";\n\nfunction json(value) {\n  return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nfunction sha256(value) {\n  return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction safeSegment(value) {\n  const segment = String(value)\n    .trim()\n    .replaceAll(/[^0-9A-Za-z._-]+/g, \"-\")\n    .replaceAll(/^-+|-+$/g, \"\");\n  if (!segment) throw new Error(\"Evalbook attempt identity is empty\");\n  return segment;\n}\n\nfunction candidateDescriptor(report, candidateId) {\n  const descriptor =\n    report.bundle.providerVersions?.[candidateId] ?? candidateId;\n  const separator = descriptor.indexOf(\":\");\n  return separator < 0\n    ? { driver: \"unknown driver\", model: descriptor }\n    : {\n        driver: descriptor.slice(0, separator),\n        model: descriptor.slice(separator + 1),\n      };\n}\n\nfunction scoreChecks(result) {\n  const dimensionChecks = Object.values(result.scorecard.dimensions).map(\n    (dimension) => ({","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/render-runner-workflow-evalbook.mjs#L4-L40","documentation":"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.","triggerScenarios":"Passing an attempt id like '///', '---', or '' (undefined coerces to 'undefined' so usually passes); a candidate id that is only spaces or symbols.","commonSituations":"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.","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"],"exampleFix":"// before\nsafeSegment(report.attemptId); // ''\n// after\nsafeSegment(report.attemptId || 'unknown-attempt');","handlingStrategy":"validation","validationCode":"if (!String(value ?? '').trim()) throw new Error('Attempt identity is empty');","typeGuard":"const hasIdentity = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"try { const seg = safeSegment(id); } catch (e) { if (e.message.includes('identity is empty')) console.error('Attempt id was:', JSON.stringify(id)); throw e; }","preventionTips":["Validate upstream report fields before rendering","Provide sensible defaults for optional identity fields","Log raw identifiers when building attempt paths"],"tags":["validation","naming","evalbook"],"backgroundTag":"empty-required-field","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}