paperclipai/paperclip · error · Error
Public viewer page differs from the trusted shell
Error message
Public viewer page differs from the trusted shell
What it means
Thrown by validatePublicViewerPage when the served public viewer HTML does not byte-match the trusted shell regenerated via publicViewerShell(trustedIndex, embeddedData). The page must be exactly the trusted index shell with only the embedded PUBLIC_VIEWER_DATA JSON substituted; any other modification is rejected to prevent tampering with the public page.
Source
Thrown at packages/paperclip-runner/scripts/public-eval-viewer.mjs:230
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.")
)
throw new Error("Public replay contains a raw tool payload");
}
}
}
export function validatePublicViewerPage(content, trustedIndex) {
const match = content.match(PUBLIC_VIEWER_DATA);
if (!match || publicViewerShell(trustedIndex, match[1]) !== content)
throw new Error("Public viewer page differs from the trusted shell");
const payload = JSON.parse(match[1]);
validatePublicChatPayload(payload);
return payload;
}
View on GitHub (pinned to 01ad858492)
Solutions
- Regenerate the viewer page using publicViewerShell with the current trusted index so it byte-matches.
- Remove any post-processing steps (injected scripts, minification) that alter the public page after generation.
- Ensure the embedded JSON serialization (key order, escaping) matches what publicViewerShell expects.
Defensive patterns
Strategy: validation
Validate before calling
const m = content.match(PUBLIC_VIEWER_DATA);
if (!m || publicViewerShell(trustedIndex, m[1]) !== content) throw new Error('viewer page drifted from trusted shell'); Try / catch
try { validatePublicViewerPage(html, trustedIndex); } catch (e) { if (e.message.includes('trusted shell')) { console.error('public page was modified after generation; regenerate it'); process.exit(1); } throw e; } Prevention
- Generate the page exclusively via publicViewerShell; forbid post-generation HTML edits.
- Disable deploy-time HTML injections (analytics/CDN transforms) for this artifact.
- Pin the trusted index version used for regeneration in CI.
When it happens
Trigger: Validating HTML content where the PUBLIC_VIEWER_DATA regex does not match, or where re-rendering the shell around the extracted JSON differs from the actual content (extra scripts, changed markup, different JSON escaping).
Common situations: Deploy pipeline injects extra tags (analytics, CSP meta) into the page; index.html was rebuilt from a different trusted version; a minifier reformatted the HTML or the embedded JSON.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Invalid status '${String(rawStatus)}'. Must be one of: ${PLU
- "tool" is required and must be a string
- "runContext" is required and must be an object
- "runContext" must include agentId, runId, companyId, and pro
- ${prefix}: the capability must be an object.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/79f1628c59d52482.
Report an issue: GitHub.