{"record":{"id":"4484263a80d07583","repo":"pbakaus/impeccable","slug":"parts-join-n","errorCode":null,"errorMessage":"${parts.join('\\n')}","messagePattern":"\\$\\{parts\\.join\\('\\\\n'\\)\\}","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/live-poll.mjs","lineNumber":126,"sourceCode":"}\n\nexport function requiresAgentReply(event) {\n  return EVENT_TYPES_NEEDING_AGENT_REPLY.has(event?.type);\n}\n\nexport async function postReply(base, token, reply) {\n  const res = await fetch(`${base}/poll`, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify(buildPollReplyPayload(token, reply)),\n  });\n  if (!res.ok) {\n    const body = await res.json().catch(() => ({}));\n    const failureLines = Array.isArray(body.failures)\n      ? body.failures.map((f) => `  ${f.file}${f.line != null ? `:${f.line}` : ''} ${f.message}`).join('\\n')\n      : null;\n    const parts = [body.error || res.statusText, body.reason, body.hint, failureLines, body._instructions].filter(Boolean);\n    throw new Error(parts.join('\\n'));\n  }\n}\n\nexport async function fetchServerStatus(base, token) {\n  const res = await fetch(`${base}/status?token=${token}`);\n  if (res.status === 401) {\n    const err = new Error('Authentication failed. The server token may have changed.');\n    err.code = 'AUTH_FAILED';\n    throw err;\n  }\n  if (!res.ok) {\n    throw new Error(`Status failed: ${res.status} ${res.statusText}`);\n  }\n  return res.json();\n}\n\nexport function isEventPending(status, eventId) {\n  return (status.pendingEvents || []).some((entry) => entry.id === eventId);","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/skill/scripts/live-poll.mjs#L108-L144","documentation":"Thrown by postReply() in live-poll.mjs after a POST to the /poll endpoint returns a non-OK HTTP status. The message is dynamically assembled by joining server-supplied fields: body.error (or res.statusText as fallback), body.reason, body.hint, a formatted list of per-file failures (body.failures with file/line/message), and body._instructions — all newline-separated. So the visible text is the server's structured rejection rendered for the console.","triggerScenarios":"postReply(base, token, reply) is called (e.g. by the live agent replying to a surfaced event). The server responds with a non-2xx status and a JSON body containing error/reason/hint/failures. Common: 4xx for a malformed reply payload, a reply referencing an already-acked or expired event, or an injection that failed server-side validation (failures[] populated with file:line message).","commonSituations":"The agent replied with a patch/injection that the server rejected (bad anchor, file not found, syntax error at a line); token mismatch surfaced as a 4xx instead of a clean 401; event lease expired and the server no longer recognizes the event id; server was upgraded and the reply schema changed.","solutions":["Read the joined message: the 'failures' lines pin point each file:line problem — fix the named locations and resend.","If the message includes a hint or _instructions block, follow it before retrying.","If it smells like an auth/stale-session issue, refresh status via fetchServerStatus to confirm the token is still valid before re-replying.","Retry only after correcting the underlying payload; an identical retry will keep failing."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate the reply payload shape before posting.\nfunction isValidReply(r) {\n  return r && typeof r.eventId !== 'undefined' && (typeof r.status === 'string' && !r.status.startsWith('--'));\n}\nif (!isValidReply(reply)) throw new Error('reply shape invalid — not posting');","typeGuard":null,"tryCatchPattern":"try {\n  await postReply(base, token, reply);\n} catch (err) {\n  // The message is newline-joined server fields; surface it whole.\n  if (/Authentication failed/.test(err.message) || err.code === 'AUTH_FAILED') throw err;\n  console.error('Reply rejected by server:\\n' + err.message);\n  // Do NOT retry identical payload — fix the cited file:line failures first.\n}","preventionTips":["Validate the reply payload (eventId, status, content) before posting.","Log the full joined message — it carries per-file failure coordinates.","Confirm token validity via fetchServerStatus before re-replying after a long pause."],"tags":["network","live-poll","server-error","http","reply"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}