{"record":{"id":"468fc18bcea09814","repo":"Yeachan-Heo/oh-my-codex","slug":"legacy-dispatch-rollback-evidence-is-malformed-or","errorCode":null,"errorMessage":"legacy dispatch rollback evidence is malformed or unrecognized","messagePattern":"legacy dispatch rollback evidence is malformed or unrecognized","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/team/state.ts","lineNumber":2096,"sourceCode":"    && request.team_name === teamName\n    && typeof request.to_worker === 'string'\n    && request.to_worker.length > 0\n    && typeof request.trigger_message === 'string'\n    && ['hook_preferred_with_fallback', 'transport_direct', 'prompt_stdin'].includes(String(request.transport_preference))\n    && typeof request.fallback_allowed === 'boolean'\n    && ['pending', 'notified', 'delivered', 'failed'].includes(String(request.status))\n    && typeof request.attempt_count === 'number'\n    && Number.isFinite(request.attempt_count)\n    && typeof request.created_at === 'string'\n    && typeof request.updated_at === 'string';\n}\n\nasync function readLegacyDispatchRequestsForRollback(teamName: string, cwd: string): Promise<TeamDispatchRequest[]> {\n  const path = dispatchRequestsPath(teamName, cwd);\n  try {\n    const raw = JSON.parse(await readFile(path, 'utf8')) as unknown;\n    if (!Array.isArray(raw) || raw.some((entry) => !isStrictLegacyDispatchRequestForRollback(entry, teamName))) {\n      throw new Error('legacy dispatch rollback evidence is malformed or unrecognized');\n    }\n    return raw as TeamDispatchRequest[];\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === 'ENOENT') return [];\n    throw error;\n  }\n}\n\nasync function writeDispatchRequests(teamName: string, requests: TeamDispatchRequest[], cwd: string): Promise<void> {\n  await writeAtomic(dispatchRequestsPath(teamName, cwd), JSON.stringify(requests, null, 2));\n  await writeBridgeDispatchCompat(teamName, requests, cwd);\n}\n\nfunction serializeDispatchRequestToBridgeRecord(request: TeamDispatchRequest): DispatchRecord {\n  return {\n    request_id: request.request_id,\n    target: request.to_worker,\n    status: request.status,","sourceCodeStart":2078,"sourceCodeEnd":2114,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/team/state.ts#L2078-L2114","documentation":"Thrown when the legacy per-team dispatch request file exists but is not a JSON array, or any entry fails strict validation as a rollback-safe TeamDispatchRequest. The file is read during rollback of dispatch requests to discover which legacy request IDs were issued for the workers being removed.","triggerScenarios":"Calling the team membership rollback path (removing workers / rolling back dispatch) when .team/<team>/dispatch-requests.json is corrupted, hand-edited, truncated, or contains entries with missing/foreign team_name fields.","commonSituations":"Concurrent writers corrupted the legacy file; a migration wrote a different schema; partial write due to crash; manual editing of the file.","solutions":["Restore or regenerate the per-team dispatch request file from a known-good backup or the authoritative bridge dispatch.json","If the file is disposable compatibility output, delete it (ENOENT returns []) so rollback proceeds with empty legacy evidence","Fix whatever process wrote non-array/non-schema JSON into the path","Check for concurrent unserialized writers to dispatchRequestsPath(teamName, cwd)"],"exampleFix":"// before: corrupted file causes throw\n// after: allow rollback to proceed with no legacy evidence\ntry {\n  await rollbackDispatch(names);\n} catch (e) {\n  if (String(e.message).startsWith('legacy dispatch rollback evidence is malformed')) {\n    await rm(dispatchRequestsPath(team, cwd), { force: true });\n    await rollbackDispatch(names);\n  } else throw e;\n}","handlingStrategy":"fallback","validationCode":"import { readFileSync } from 'node:fs';\nfunction legacyDispatchFileOk(path: string): boolean {\n  try {\n    const raw = JSON.parse(readFileSync(path, 'utf8'));\n    return Array.isArray(raw);\n  } catch { return false; }\n}","typeGuard":"function isLegacyDispatchFileViable(path: string): boolean {\n  return legacyDispatchFileOk(path);\n}","tryCatchPattern":"catch (e) { if ((e as Error).message.includes('legacy dispatch rollback evidence')) { /* reset/regenerate legacy file, retry rollback once */ } else throw e; }","preventionTips":["Never hand-edit the legacy dispatch file","Keep a single serialized writer per team's dispatch file","Treat the file as regenerable compatibility output"],"tags":["dispatch","rollback","json-validation","team-state"],"backgroundTag":"malformed-json-file","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}