{"record":{"id":"17c15b7e4ddfe3e2","repo":"tinyhumansai/openhuman","slug":"duplicate-branch-agent-branch","errorCode":null,"errorMessage":"duplicate branch \"${agent.branch}\"","messagePattern":"duplicate branch \"(.+?)\"","errorType":"validation","errorClass":"SpecError","httpStatus":null,"severity":"error","filePath":"scripts/agent-batch/lib.mjs","lineNumber":136,"sourceCode":"      throw new SpecError(\n        `branch must match cursor/<id>-<issue>-<slug> (got \"${agent.branch}\")`,\n        `${at}.branch`,\n      );\n    }\n    if (m[1] !== agent.id) {\n      throw new SpecError(\n        `branch id segment \"${m[1]}\" does not match agent id \"${agent.id}\"`,\n        `${at}.branch`,\n      );\n    }\n    if (Number(m[2]) !== agent.issue) {\n      throw new SpecError(\n        `branch issue segment \"${m[2]}\" does not match agent issue ${agent.issue}`,\n        `${at}.branch`,\n      );\n    }\n    if (seenBranch.has(agent.branch)) {\n      throw new SpecError(`duplicate branch \"${agent.branch}\"`, `${at}.branch`);\n    }\n    seenBranch.add(agent.branch);\n    if (!Array.isArray(agent.owned_paths) || agent.owned_paths.length === 0) {\n      throw new SpecError(\n        \"owned_paths must be a non-empty array\",\n        `${at}.owned_paths`,\n      );\n    }\n    for (let j = 0; j < agent.owned_paths.length; j++) {\n      const p = agent.owned_paths[j];\n      if (typeof p !== \"string\" || p.length === 0) {\n        throw new SpecError(\n          \"must be a non-empty string\",\n          `${at}.owned_paths[${j}]`,\n        );\n      }\n      if (p.includes(\"*\") || p.includes(\"?\")) {\n        throw new SpecError(","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/agent-batch/lib.mjs#L118-L154","documentation":"Branch strings must be unique across the batch — the seenBranch Set rejects a second agent declaring the same branch, with the duplicated value and path \"agents[i].branch\". Uniqueness matters because each agent's work is pushed to its own git branch; two agents sharing one would clobber each other. Given the id/issue cross-checks, this usually means fully duplicated entries.","triggerScenarios":"Two agents with identical branch strings — typically a whole duplicated agent entry where id/issue checks were fixed to be distinct but the branch slug was left identical, or the same agent pasted twice with only cosmetic edits.","commonSituations":"Copy-paste growth of a spec where branches were templated as cursor/a01-5312-... and never varied; merge of two spec files that both contain an agent with the same branch.","solutions":["Make each branch unique by construction: cursor/<id>-<issue>-<slug> with that agent's own id and issue","Since id and issue are already forced unique, a duplicate branch almost always means the branch was not regenerated after fixing those fields — regenerate it","Check: new Set(agents.map(a => a.branch)).size === agents.length"],"exampleFix":"// before\n{ \"id\": \"a01\", \"issue\": 5312, \"branch\": \"cursor/a01-5312-shared-slug\" }\n{ \"id\": \"a02\", \"issue\": 5313, \"branch\": \"cursor/a01-5312-shared-slug\" }\n\n// after\n{ \"id\": \"a01\", \"issue\": 5312, \"branch\": \"cursor/a01-5312-fix-ci-timeout\" }\n{ \"id\": \"a02\", \"issue\": 5313, \"branch\": \"cursor/a02-5313-tighten-lint\" }","handlingStrategy":"validation","validationCode":"const branches = spec.agents.map((a) => a.branch);\nif (new Set(branches).size !== branches.length) {\n  console.error(\"duplicate branch names across agents\");\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  validateSpec(spec);\n} catch (e) {\n  if (e instanceof SpecError && /duplicate branch/.test(e.message)) {\n    console.error(`regenerate the copied branch: ${e.message}`);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Because id and issue are already forced unique, always regenerate the whole branch string after fixing either field","Assert branch uniqueness alongside id/issue uniqueness in your pre-flight check"],"tags":["validation","json","spec","agent-batch","uniqueness","git"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}