paperclipai/paperclip · error · Error
Public replay contains an unprojected item
Error message
Public replay contains an unprojected item
What it means
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.
Source
Thrown at packages/paperclip-runner/scripts/public-eval-viewer.mjs:203
call,
"id turnId operationId version providerRequest dispatchedCommand outcome result redactions threadAnchorId",
);
fields(call.result, "outcome detail");
if (call.result.detail !== "Tool payload withheld from public replay.")
throw new Error("Public replay contains raw call evidence");
}
for (const turn of payload.view.turns ?? []) {
fields(turn, "id ordinal mode toolCallCount at stoppedByUser items");
for (const item of turn.items ?? []) {
if (
![
"user_message",
"agent_message",
"tool_activity",
"system_notice",
].includes(item.kind)
)
throw new Error("Public replay contains an unprojected item");
const shapes = {
user_message: "kind id at author body streaming",
agent_message: "kind id at author body streaming",
tool_activity:
"kind id at operationId status summary input result evidenceRef",
system_notice: "kind id at glyph text evidenceRef",
};
fields(item, shapes[item.kind]);
if (item.evidenceRef) fields(item.evidenceRef, "section recordId");
if (
item.kind === "tool_activity" &&
(JSON.stringify(item.input) !==
JSON.stringify({
detail: "Arguments withheld from public replay.",
}) ||
Object.keys(item.result).sort().join(",") !== "detail,outcome" ||
item.result.detail !== "Tool payload withheld from public replay.")
)View on GitHub (pinned to 01ad858492)
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.
Example fix
// before
items.push({ kind: 'internal_debug', ... });
// after
if (PUBLIC_KINDS.has(item.kind)) items.push(projectItem(item)); // internal_debug dropped Defensive patterns
Strategy: validation
Validate before calling
const KINDS = ['user_message','agent_message','tool_activity','system_notice'];
if (turns.some(t => (t.items ?? []).some(i => !KINDS.includes(i.kind)))) throw new Error('unknown item kind in public view'); Type guard
function isPublicItemKind(k) { return ['user_message','agent_message','tool_activity','system_notice'].includes(k); } Prevention
- 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.
When it happens
Trigger: Validating a payload where any view.turns[i].items[j].kind is not one of the four allowed kinds.
Common situations: 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.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Public replay contains unprojected evidence
- sandbox runtime asset key is not a simple path segment: ${ke
- Invalid GitHub launcher run ID
- Unexpected trusted viewer asset
- Public attempt must contain the read-only public chat projec
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/39995f4ee71d1f76.
Report an issue: GitHub.