{"record":{"id":"c875769138ad2591","repo":"tinyhumansai/openhuman","slug":"base-branch-must-be-main-got-spec-base-branc","errorCode":null,"errorMessage":"base_branch must be \"main\" (got \"${spec.base_branch}\")","messagePattern":"base_branch must be \"main\" \\(got \"(.+?)\"\\)","errorType":"validation","errorClass":"SpecError","httpStatus":null,"severity":"error","filePath":"scripts/agent-batch/lib.mjs","lineNumber":63,"sourceCode":"  }\n  for (const key of REQUIRED_TOP) {\n    if (!(key in spec))\n      throw new SpecError(`missing required top-level field \"${key}\"`);\n  }\n  if (\n    typeof spec.batch_id !== \"string\" ||\n    !/^[a-z0-9][a-z0-9-]*$/.test(spec.batch_id)\n  ) {\n    throw new SpecError(\"batch_id must be a kebab-case slug\", \"batch_id\");\n  }\n  if (spec.base_repo !== \"tinyhumansai/openhuman\") {\n    throw new SpecError(\n      `base_repo must be \"tinyhumansai/openhuman\" (got \"${spec.base_repo}\")`,\n      \"base_repo\",\n    );\n  }\n  if (spec.base_branch !== \"main\") {\n    throw new SpecError(\n      `base_branch must be \"main\" (got \"${spec.base_branch}\")`,\n      \"base_branch\",\n    );\n  }\n  if (!Number.isInteger(spec.tracking_issue) || spec.tracking_issue <= 0) {\n    throw new SpecError(\n      \"tracking_issue must be a positive integer\",\n      \"tracking_issue\",\n    );\n  }\n  if (!Array.isArray(spec.agents) || spec.agents.length === 0) {\n    throw new SpecError(\"agents must be a non-empty array\", \"agents\");\n  }\n  if (spec.agents.length > 25) {\n    throw new SpecError(\n      `batch size ${spec.agents.length} exceeds hard cap of 25`,\n      \"agents\",\n    );","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/agent-batch/lib.mjs#L45-L81","documentation":"validateSpec() requires the top-level base_branch to be exactly \"main\"; any other branch name throws with the got-value shown. Batch agents are only ever cut from upstream/main per repo policy (the AGENTS.md rule \"Never write code on main\" work branches derive from main), so basing a batch on release/feature branches is rejected.","triggerScenarios":"A spec with \"base_branch\": \"master\", \"release\", \"develop\", or a PR branch name like \"feat/batch-august\" passed to validateSpec or the agent-batch CLI entry points.","commonSituations":"Porting a spec from an older repo default of \"master\"; attempting to replay a batch against the long-lived release branch; copy-pasting from a workflow that targets release.","solutions":["Change base_branch to \"main\"","If the work must target release, note the batch tooling does not support it — run the batch off main and let the normal promote-main-to-release flow carry it","Remove the field only if you also want the earlier REQUIRED_TOP \"missing required top-level field\" error instead — it is mandatory"],"exampleFix":"// before\n\"base_branch\": \"master\"\n\n// after\n\"base_branch\": \"main\"","handlingStrategy":"validation","validationCode":"if (spec.base_branch !== \"main\") {\n  console.error(`base_branch must be main, got ${spec.base_branch}`);\n  process.exit(1);\n}","typeGuard":"/** @param {unknown} v */\nfunction isMainBranch(v) {\n  return v === \"main\";\n}","tryCatchPattern":"try {\n  validateSpec(spec);\n} catch (e) {\n  if (e instanceof SpecError && e.path === \"base_branch\") {\n    console.error(`fix ${specPath}: ${e.message}`);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Remember the batch tooling only supports main — do not try to adapt specs from release-targeting workflows","Pin base_branch in the template so editors cannot change it accidentally"],"tags":["validation","json","spec","agent-batch","git"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}