{"record":{"id":"39995f4ee71d1f76","repo":"paperclipai/paperclip","slug":"public-replay-contains-an-unprojected-item","errorCode":null,"errorMessage":"Public replay contains an unprojected item","messagePattern":"Public replay contains an unprojected item","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/public-eval-viewer.mjs","lineNumber":203,"sourceCode":"      call,\n      \"id turnId operationId version providerRequest dispatchedCommand outcome result redactions threadAnchorId\",\n    );\n    fields(call.result, \"outcome detail\");\n    if (call.result.detail !== \"Tool payload withheld from public replay.\")\n      throw new Error(\"Public replay contains raw call evidence\");\n  }\n  for (const turn of payload.view.turns ?? []) {\n    fields(turn, \"id ordinal mode toolCallCount at stoppedByUser items\");\n    for (const item of turn.items ?? []) {\n      if (\n        ![\n          \"user_message\",\n          \"agent_message\",\n          \"tool_activity\",\n          \"system_notice\",\n        ].includes(item.kind)\n      )\n        throw new Error(\"Public replay contains an unprojected item\");\n      const shapes = {\n        user_message: \"kind id at author body streaming\",\n        agent_message: \"kind id at author body streaming\",\n        tool_activity:\n          \"kind id at operationId status summary input result evidenceRef\",\n        system_notice: \"kind id at glyph text evidenceRef\",\n      };\n      fields(item, shapes[item.kind]);\n      if (item.evidenceRef) fields(item.evidenceRef, \"section recordId\");\n      if (\n        item.kind === \"tool_activity\" &&\n        (JSON.stringify(item.input) !==\n          JSON.stringify({\n            detail: \"Arguments withheld from public replay.\",\n          }) ||\n          Object.keys(item.result).sort().join(\",\") !== \"detail,outcome\" ||\n          item.result.detail !== \"Tool payload withheld from public replay.\")\n      )","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/public-eval-viewer.mjs#L185-L221","documentation":"Thrown by validatePublicChatPayload when a turn item has a 'kind' outside the allowlist user_message, agent_message, tool_activity, system_notice. Public replays expose only these projected item kinds; any other kind (e.g. internal-only items) indicates an unprojected item leaked through.","triggerScenarios":"Validating a payload where any view.turns[i].items[j].kind is not one of the four allowed kinds.","commonSituations":"A new internal item kind added upstream that the projector does not map or drop; replaying an old run whose items contain retired kinds; a projection filter accidentally disabled.","solutions":["Update the projection step to map or drop the unknown item kind before building the public view.","If the kind is legitimately public, add it to the allowlist in validatePublicChatPayload together with a shape entry.","Regenerate the public replay from the original run after fixing the projector."],"exampleFix":"// before\nitems.push({ kind: 'internal_debug', ... });\n// after\nif (PUBLIC_KINDS.has(item.kind)) items.push(projectItem(item)); // internal_debug dropped","handlingStrategy":"validation","validationCode":"const KINDS = ['user_message','agent_message','tool_activity','system_notice'];\nif (turns.some(t => (t.items ?? []).some(i => !KINDS.includes(i.kind)))) throw new Error('unknown item kind in public view');","typeGuard":"function isPublicItemKind(k) { return ['user_message','agent_message','tool_activity','system_notice'].includes(k); }","tryCatchPattern":null,"preventionTips":["When adding a new internal item kind, update the projector's drop/map list in the same change.","Filter items through a single allowlist constant used by both projector and validator.","Test the projector against runs containing every known kind."],"tags":["validation","security","replay"],"backgroundTag":"invalid-enum-value","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"}