{"record":{"id":"aba923416eae64a6","repo":"tinyhumansai/openhuman","slug":"missing-required-field-key","errorCode":null,"errorMessage":"missing required field \"${key}\"","messagePattern":"missing required field \"(.+?)\"","errorType":"validation","errorClass":"SpecError","httpStatus":null,"severity":"error","filePath":"scripts/agent-batch/lib.mjs","lineNumber":95,"sourceCode":"  if (spec.agents.length > 25) {\n    throw new SpecError(\n      `batch size ${spec.agents.length} exceeds hard cap of 25`,\n      \"agents\",\n    );\n  }\n\n  const seenId = new Set();\n  const seenIssue = new Set();\n  const seenBranch = new Set();\n  for (let i = 0; i < spec.agents.length; i++) {\n    const agent = spec.agents[i];\n    const at = `agents[${i}]`;\n    if (!agent || typeof agent !== \"object\" || Array.isArray(agent)) {\n      throw new SpecError(\"must be an object\", at);\n    }\n    for (const key of REQUIRED_AGENT) {\n      if (!(key in agent))\n        throw new SpecError(`missing required field \"${key}\"`, at);\n    }\n    if (typeof agent.id !== \"string\" || !/^a\\d{2,3}$/.test(agent.id)) {\n      throw new SpecError(\n        `id must match /^a\\\\d{2,3}$/ (got \"${agent.id}\")`,\n        `${at}.id`,\n      );\n    }\n    if (seenId.has(agent.id))\n      throw new SpecError(`duplicate id \"${agent.id}\"`, `${at}.id`);\n    seenId.add(agent.id);\n    if (!Number.isInteger(agent.issue) || agent.issue <= 0) {\n      throw new SpecError(\"issue must be a positive integer\", `${at}.issue`);\n    }\n    if (seenIssue.has(agent.issue)) {\n      throw new SpecError(`duplicate issue #${agent.issue}`, `${at}.issue`);\n    }\n    seenIssue.add(agent.issue);\n    if (typeof agent.title !== \"string\" || agent.title.trim().length === 0) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/agent-batch/lib.mjs#L77-L113","documentation":"Every agent object must contain all five REQUIRED_AGENT keys: id, issue, title, branch, owned_paths. The thrown message interpolates the first missing key name and the path is the agent position (\"agents[i]\"), so the report reads e.g. \"agents[2]: missing required field \\\"branch\\\"\". Only presence is checked here — type/format is validated by subsequent checks.","triggerScenarios":"An agent entry that omits owned_paths (the most commonly forgotten), omits branch, or uses a typo'd key like \"branches\" or \"titles\" so the real key is missing.","commonSituations":"Copying a partial template; renaming keys when porting from another tool's schema; hand-trimming an agent to make it \"smaller\".","solutions":["Add the named missing field to the agent at the reported index","Compare against REQUIRED_AGENT = [\"id\", \"issue\", \"title\", \"branch\", \"owned_paths\"] and add every absent key","Check for spelling/pluralization drift (branches vs branch, ownedPaths vs owned_paths)"],"exampleFix":"// before\n{ \"id\": \"a01\", \"issue\": 5312, \"title\": \"Fix CI\", \"branch\": \"cursor/a01-5312-fix-ci\" }\n\n// after\n{ \"id\": \"a01\", \"issue\": 5312, \"title\": \"Fix CI\", \"branch\": \"cursor/a01-5312-fix-ci\", \"owned_paths\": [\"scripts/ci/\"] }","handlingStrategy":"validation","validationCode":"const REQUIRED_AGENT = [\"id\", \"issue\", \"title\", \"branch\", \"owned_paths\"];\nfor (const [i, a] of spec.agents.entries()) {\n  for (const k of REQUIRED_AGENT) {\n    if (!(k in a)) console.error(`agents[${i}] missing \"${k}\"`);\n  }\n}","typeGuard":"/** @param {unknown} v */\nfunction isAgentShaped(v) {\n  if (typeof v !== \"object\" || v === null) return false;\n  return [\"id\", \"issue\", \"title\", \"branch\", \"owned_paths\"].every((k) => k in v);\n}","tryCatchPattern":"try {\n  validateSpec(spec);\n} catch (e) {\n  if (e instanceof SpecError && /^agents\\[\\d+]$/.test(e.path ?? \"\")) {\n    console.error(`agent at ${e.path} incomplete: ${e.message}`);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Start every agent entry by pasting the full five-field skeleton, then fill it in","Validate incrementally while authoring (node -e 'validateSpec(JSON.parse(...))') instead of only at launch"],"tags":["validation","json","spec","agent-batch","required-fields"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}