{"record":{"id":"f635f9aaf735e4aa","repo":"paperclipai/paperclip","slug":"unknown-public-chat-projection-field","errorCode":null,"errorMessage":"Unknown public chat projection field","messagePattern":"Unknown public chat projection field","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/public-eval-viewer.mjs","lineNumber":91,"sourceCode":"    \"disposition\",\n    \"passed\",\n    \"checks\",\n    \"view\",\n    \"devtools\",\n    \"navigation\",\n    \"run\",\n    \"publication\",\n  ]);\n  if (Object.keys(payload).some((key) => !allowed.has(key)))\n    throw new Error(\"Unknown public chat payload field\");\n  const fields = (value, names) => {\n    if (\n      !value ||\n      typeof value !== \"object\" ||\n      Array.isArray(value) ||\n      Object.keys(value).some((key) => !names.split(\" \").includes(key))\n    )\n      throw new Error(\"Unknown public chat projection field\");\n  };\n  fields(payload.publication, \"schema notice\");\n  fields(payload.navigation, \"suiteHref previous next\");\n  for (const link of [payload.navigation.previous, payload.navigation.next])\n    if (link !== null) fields(link, \"label href\");\n  fields(\n    payload.run,\n    \"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\",\n  );\n  if (\n    payload.run.effectiveModelHistory?.length ||\n    payload.run.managedProfile != null ||\n    payload.run.acpxProfile != null\n  )\n    throw new Error(\"Public replay contains private provider metadata\");\n  if (payload.run.usage !== null)\n    fields(\n      payload.run.usage,","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/public-eval-viewer.mjs#L73-L109","documentation":"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\".","triggerScenarios":"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.","commonSituations":"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.","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})."],"exampleFix":"// before\nnavigation: { suiteHref, previous, next, breadcrumbs },\n// after\nnavigation: { suiteHref, previous, next }, // breadcrumbs not allowlisted","handlingStrategy":"type-guard","validationCode":"const matches = (obj, names) => obj && typeof obj === \"object\" && !Array.isArray(obj) && Object.keys(obj).every((k) => names.split(\" \").includes(k));\nif (!matches(payload.run, \"model provider driver ...\")) console.warn(\"run projection has unexpected fields\");","typeGuard":"const isProjection = (v, names) => Boolean(v) && typeof v === \"object\" && !Array.isArray(v) && Object.keys(v).every((k) => names.split(\" \").includes(k));","tryCatchPattern":"try {\n  validatePublicChatPayload(payload);\n} catch (err) {\n  if (err.message === \"Unknown public chat projection field\") {\n    console.error(\"A nested projection has extra/renamed fields; diff generator output against the allowlists\");\n  }\n  throw err;\n}","preventionTips":["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"],"tags":["validation","schema","allowlist"],"backgroundTag":"schema-validation-failed","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}