paperclipai/paperclip · error · Error
Unknown public chat projection field
Error message
Unknown public chat projection field
What it means
The local fields() helper validates that a nested projection object is a non-null, non-array object whose keys are exactly within a space-separated allowlist (e.g. publication: "schema notice", navigation: "suiteHref previous next", run: the long field list, checks and their definition/anchor sub-objects). Any missing/extra key, wrong type, array, or null value yields "Unknown public chat projection field".
Source
Thrown at packages/paperclip-runner/scripts/public-eval-viewer.mjs:91
"disposition",
"passed",
"checks",
"view",
"devtools",
"navigation",
"run",
"publication",
]);
if (Object.keys(payload).some((key) => !allowed.has(key)))
throw new Error("Unknown public chat payload field");
const fields = (value, names) => {
if (
!value ||
typeof value !== "object" ||
Array.isArray(value) ||
Object.keys(value).some((key) => !names.split(" ").includes(key))
)
throw new Error("Unknown public chat projection field");
};
fields(payload.publication, "schema notice");
fields(payload.navigation, "suiteHref previous next");
for (const link of [payload.navigation.previous, payload.navigation.next])
if (link !== null) fields(link, "label href");
fields(
payload.run,
"model provider driver providerVersion runnerProvider acpxAgent acpxProfile requestedModel effectiveModelHistory configuration sessionId providerSessionId agentVersion managedProfile retainedSession retainedSessionStatus fixtureDigest runnerPackageDigest runnerdDigest startedAt finishedAt durationMs runnerBuild initialRevision finalRevision usage",
);
if (
payload.run.effectiveModelHistory?.length ||
payload.run.managedProfile != null ||
payload.run.acpxProfile != null
)
throw new Error("Public replay contains private provider metadata");
if (payload.run.usage !== null)
fields(
payload.run.usage,View on GitHub (pinned to 01ad858492)
Solutions
- Compare the offending object's keys against the exact allowlist string passed to fields() and remove or rename the extra field.
- If the projection legitimately gained a field, extend the corresponding names string in validatePublicChatPayload().
- Regenerate the payload with the generator version matching this validator to realign projections.
- Fix null/array values: ensure each projected field is a plain object (e.g. navigation.previous may be null, but when present must be {label, href}).
Example fix
// before
navigation: { suiteHref, previous, next, breadcrumbs },
// after
navigation: { suiteHref, previous, next }, // breadcrumbs not allowlisted Defensive patterns
Strategy: type-guard
Validate before calling
const matches = (obj, names) => obj && typeof obj === "object" && !Array.isArray(obj) && Object.keys(obj).every((k) => names.split(" ").includes(k));
if (!matches(payload.run, "model provider driver ...")) console.warn("run projection has unexpected fields"); Type guard
const isProjection = (v, names) => Boolean(v) && typeof v === "object" && !Array.isArray(v) && Object.keys(v).every((k) => names.split(" ").includes(k)); Try / catch
try {
validatePublicChatPayload(payload);
} catch (err) {
if (err.message === "Unknown public chat projection field") {
console.error("A nested projection has extra/renamed fields; diff generator output against the allowlists");
}
throw err;
} Prevention
- Derive both the projector output and the validator allowlist from one shared schema definition
- Rename fields in the generator and validator in the same change
- Add per-section unit tests asserting each projection object's exact key set
- Use pick()-style explicit key selection when projecting, never object spread of internal objects
When it happens
Trigger: Calling validatePublicChatPayload where any of the projected sub-objects (publication, navigation, navigation.previous/next, run, view, view.identity, view.issue, view.composer, view.connection, view.evidence, each check, check.definition, check.anchor, run.usage, evidence.calls entries, turns) has an extra/renamed field, is an array, or is null/undefined.
Common situations: Renaming a field in the generator (e.g. detail -> message) without updating the allowlist string; adding a field like check.definition.title; accidentally serializing navigation links as arrays; a null sub-object where an object was expected.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Unknown public chat payload field
- Worktree seed manifest is missing source path diagnostics.
- unsupported request schema
- Public attempt must contain the read-only public chat projec
- Refusing non-allowlisted public protocol eval path ${file}
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/f635f9aaf735e4aa.
Report an issue: GitHub.