{"record":{"id":"265ff5947257d6c8","repo":"paperclipai/paperclip","slug":"public-protocol-eval-file-exceeds-its-size-boundar","errorCode":null,"errorMessage":"Public protocol eval file exceeds its size boundary: ${file}","messagePattern":"Public protocol eval file exceeds its size boundary: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs","lineNumber":164,"sourceCode":"  const hasChat = files.some((file) =>\n    /^attempts\\/[^/]+\\/index\\.html$/.test(file),\n  );\n  const viewer = hasChat ? await trustedViewerFiles(viewerRoot) : null;\n  if (!files.includes(\"index.html\") || !files.includes(\"campaign.json\")) {\n    throw new Error(\n      \"Public protocol eval report requires index.html and campaign.json\",\n    );\n  }\n  for (const file of files) {\n    if (!isPublicProtocolEvalPath(file)) {\n      throw new Error(\n        `Refusing non-allowlisted public protocol eval path ${file}`,\n      );\n    }\n    const absolute = resolve(root, ...file.split(\"/\"));\n    const metadata = await stat(absolute);\n    if (metadata.size === 0 || metadata.size > 12 * 1024 * 1024) {\n      throw new Error(\n        `Public protocol eval file exceeds its size boundary: ${file}`,\n      );\n    }\n    if (file.startsWith(\"viewer/\")) {\n      const expected = viewer?.files.get(file);\n      if (!expected || !expected.equals(await readFile(absolute)))\n        throw new Error(\n          `Public viewer asset differs from trusted build: ${file}`,\n        );\n      continue;\n    }\n    const content = await readFile(absolute, \"utf8\");\n    const richAttempt = /^attempts\\/[^/]+\\/index\\.html$/.test(file);\n    const payload = richAttempt\n      ? validatePublicViewerPage(content, viewer.index)\n      : null;\n    if (!richAttempt) {\n      for (const pattern of CREDENTIAL_PATTERNS) {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs#L146-L182","documentation":"Each allowlisted file in the public report is stat'ed and must be non-empty and at most 12 MiB (12 * 1024 * 1024 bytes). A zero-byte file or an oversized file aborts publication naming the file, guarding against truncated or bloated assets reaching the public host.","triggerScenarios":"Publishing when any allowlisted file is 0 bytes (interrupted write/disk-full) or larger than 12 MiB (an attempt HTML with embedded base64 screenshots, a huge campaign.json).","commonSituations":"Disk-full or killed build left an empty index.html; an attempt page embedded base64 images pushing past 12 MiB; campaign.json grew with accumulated history.","solutions":["Inspect the named file: if empty, regenerate the report so it is written completely, then re-run.","If the file is too large, shrink it (strip inline base64 images, link to hosted assets, split the page) so it is under 12 MiB.","If large files are legitimately needed, raise the 12 MiB boundary in validatePublicProtocolEvalReport deliberately and document why."],"exampleFix":"// before (file 14 MB with embedded base64 screenshots)\n<img src=\"data:image/png;base64,...\">\n// after\n<img src=\"https://cdn.example.com/shots/a1.png\">  // file back under 12 MiB","handlingStrategy":"validation","validationCode":"import { statSync } from 'node:fs';\nconst MAX = 12 * 1024 * 1024;\nconst offenders = allReportFiles(reportRoot)\n  .map((f) => [f, statSync(`${reportRoot}/${f}`)])\n  .filter(([, s]) => s.size === 0 || s.size > MAX);\nif (offenders.length)\n  throw new Error(`size-boundary violations: ${offenders.map(([f, s]) => `${f}=${s.size}`).join(', ')}`);","typeGuard":null,"tryCatchPattern":"try {\n  await publishReport(root);\n} catch (err) {\n  if (String(err.message).startsWith('Public protocol eval file exceeds its size boundary')) {\n    console.error('Regenerate (empty file) or shrink (<12MiB) the named file:', err.message);\n  } else throw err;\n}","preventionTips":["Check the generator finished writing every file (no zero-byte outputs) before publishing.","Avoid inlining large base64 assets in attempt HTML; link to hosted assets instead.","Monitor campaign.json growth if history accumulates; prune or split when it approaches 12 MiB."],"tags":["validation","file-size","publish-script"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}