paperclipai/paperclip · error · Error
Public replay contains unprojected evidence
Error message
Public replay contains unprojected evidence
What it means
Thrown by validatePublicChatPayload in the public eval viewer script. The public replay payload is supposed to be a projected view where the 'parity' evidence section (and similar sections) are either absent or empty arrays, since raw evidence must not leak into a public artifact. If a projected section still contains items, the projection step was skipped or buggy, so the validator throws.
Source
Thrown at packages/paperclip-runner/scripts/public-eval-viewer.mjs:181
visit(child, name);
}
}
};
visit(payload);
for (const section of [
"tools",
"authorization",
"control_plane",
"runner",
"state",
"traceability",
"parity",
]) {
if (
!Array.isArray(payload.view.evidence?.[section]) ||
payload.view.evidence[section].length
)
throw new Error("Public replay contains unprojected evidence");
}
for (const call of payload.view.evidence.calls) {
fields(
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",View on GitHub (pinned to 01ad858492)
Solutions
- Run the evidence projection step so evidence.parity (and all projected sections) are emitted as empty arrays before validation.
- Check the code that builds payload.view.evidence to ensure every section iterated here is cleared for public output.
- If the payload was edited by hand, remove the leaked parity evidence entries.
Example fix
// before view.evidence.parity = internalParityResults; // after view.evidence.parity = []; // projected: public replay carries no parity evidence
Defensive patterns
Strategy: validation
Validate before calling
const projected = ['parity'].every(s => Array.isArray(view.evidence?.[s]) && view.evidence[s].length === 0);
if (!projected) throw new Error('evidence sections must be empty in public payload'); Type guard
function isProjectedEvidence(e) { return Array.isArray(e?.parity) && e.parity.length === 0; } Prevention
- Always run the projection/redaction step before validating a public payload.
- Add a unit test asserting all projected evidence sections are empty arrays.
- Never hand-edit public replay JSON.
When it happens
Trigger: Calling validatePublicChatPayload with a payload whose payload.view.evidence.parity (or another iterated section) is a non-empty array; also triggered when the section is not an array at all.
Common situations: Regenerating a public replay without running the evidence-projection/redaction step; hand-editing the JSON and pasting internal evidence; a code change adding a new evidence section that the projector does not clear.
Related errors
- Public replay contains an unprojected item
- 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/ac37e5b67161f6d6.
Report an issue: GitHub.