{"record":{"id":"8d39478e9da448d0","repo":"tinyhumansai/openhuman","slug":"base-repo-must-be-tinyhumansai-openhuman-got","errorCode":null,"errorMessage":"base_repo must be \"tinyhumansai/openhuman\" (got \"${spec.base_repo}\")","messagePattern":"base_repo must be \"tinyhumansai/openhuman\" \\(got \"(.+?)\"\\)","errorType":"validation","errorClass":"SpecError","httpStatus":null,"severity":"error","filePath":"scripts/agent-batch/lib.mjs","lineNumber":57,"sourceCode":"\n// Validate a parsed spec. Returns the spec on success, throws SpecError on\n// any policy violation. The caller is responsible for printing.\nexport function validateSpec(spec) {\n  if (!spec || typeof spec !== \"object\" || Array.isArray(spec)) {\n    throw new SpecError(\"spec must be a JSON object\");\n  }\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\");","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/agent-batch/lib.mjs#L39-L75","documentation":"validateSpec() hard-pins the top-level base_repo to exactly \"tinyhumansai/openhuman\"; any other value (or non-string) throws. The batch tooling is only sanctioned to fork/branch from the upstream repository, so forks, mirrors, or renamed remotes are rejected outright. The offending value is interpolated into the message so the diff from the expected literal is visible.","triggerScenarios":"Running validateSpec on a spec with \"base_repo\": \"yourname/openhuman\" (a fork), \"base_repo\": \"tinyhumansai/opencompany\" (wrong product), a missing-but-present null, or a repo string with different case such as \"TinyHumansAI/OpenHuman\".","commonSituations":"An operator templating a spec from their own fork checkout; a copy-paste from another TinyHumans repo's batch spec; case-normalization by an editor or YAML-to-JSON converter.","solutions":["Set base_repo to the literal \"tinyhumansai/openhuman\"","If you intended to run against a fork, note the tool refuses this by design — re-point the spec at upstream and branch from upstream/main","Check for stray whitespace or case differences in the JSON value"],"exampleFix":"// before\n\"base_repo\": \"myfork/openhuman\"\n\n// after\n\"base_repo\": \"tinyhumansai/openhuman\"","handlingStrategy":"validation","validationCode":"if (spec.base_repo !== \"tinyhumansai/openhuman\") {\n  console.error(`base_repo must be tinyhumansai/openhuman, got ${spec.base_repo}`);\n  process.exit(1);\n}","typeGuard":"/** @param {unknown} v */\nfunction isUpstreamRepo(v) {\n  return v === \"tinyhumansai/openhuman\";\n}","tryCatchPattern":"try {\n  validateSpec(spec);\n} catch (e) {\n  if (e instanceof SpecError && e.path === \"base_repo\") {\n    // point the operator at the spec file, not the tool\n    console.error(`fix ${specPath}: ${e.message}`);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Treat base_repo as a constant in spec templates — never parameterize it","If specs are generated, assert the literal early in the generator, not only at validation time"],"tags":["validation","json","spec","agent-batch","repository"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}