tinyhumansai/openhuman · error · SpecError
issue must be a positive integer
Error message
issue must be a positive integer
What it means
Per-agent issue must be a positive integer (Number.isInteger && > 0) — each agent maps to exactly one distinct GitHub issue. Like the top-level tracking_issue, no string coercion happens, so "5312" fails. Path is "agents[i].issue".
Source
Thrown at scripts/agent-batch/lib.mjs:107
const at = `agents[${i}]`;
if (!agent || typeof agent !== "object" || Array.isArray(agent)) {
throw new SpecError("must be an object", at);
}
for (const key of REQUIRED_AGENT) {
if (!(key in agent))
throw new SpecError(`missing required field "${key}"`, at);
}
if (typeof agent.id !== "string" || !/^a\d{2,3}$/.test(agent.id)) {
throw new SpecError(
`id must match /^a\\d{2,3}$/ (got "${agent.id}")`,
`${at}.id`,
);
}
if (seenId.has(agent.id))
throw new SpecError(`duplicate id "${agent.id}"`, `${at}.id`);
seenId.add(agent.id);
if (!Number.isInteger(agent.issue) || agent.issue <= 0) {
throw new SpecError("issue must be a positive integer", `${at}.issue`);
}
if (seenIssue.has(agent.issue)) {
throw new SpecError(`duplicate issue #${agent.issue}`, `${at}.issue`);
}
seenIssue.add(agent.issue);
if (typeof agent.title !== "string" || agent.title.trim().length === 0) {
throw new SpecError("title must be a non-empty string", `${at}.title`);
}
const m = BRANCH_RE.exec(agent.branch);
if (!m) {
throw new SpecError(
`branch must match cursor/<id>-<issue>-<slug> (got "${agent.branch}")`,
`${at}.branch`,
);
}
if (m[1] !== agent.id) {
throw new SpecError(
`branch id segment "${m[1]}" does not match agent id "${agent.id}"`,View on GitHub (pinned to a221052e0d)
Solutions
- Open the GitHub issue for that agent, then set the unquoted positive integer
- Remove quotes / fix arithmetic so the value is an integer > 0
- Ensure it does not collide with another agent's issue (else error 191 fires next)
Example fix
// before
{ "id": "a02", "issue": 0, ... }
// after
{ "id": "a02", "issue": 5313, ... } Defensive patterns
Strategy: validation
Validate before calling
for (const [i, a] of spec.agents.entries()) {
if (!Number.isInteger(a.issue) || a.issue <= 0) {
console.error(`agents[${i}].issue must be a positive integer`);
process.exit(1);
}
} Type guard
/** @param {unknown} v */
function isPositiveInt(v) {
return typeof v === "number" && Number.isInteger(v) && v > 0;
} Try / catch
try {
validateSpec(spec);
} catch (e) {
if (e instanceof SpecError && e.path?.endsWith(".issue")) {
console.error(`agent issue number bad: ${e.message}`);
process.exit(1);
}
throw e;
} Prevention
- Open all agent issues before authoring the spec so no placeholders remain
- Grep the spec for "issue": 0 to catch placeholders before validation
When it happens
Trigger: "issue": 0 (placeholder not replaced), -1, 12.5, "5312" (quoted), or null inside an agent entry.
Common situations: Writing the spec before the issues are opened and leaving 0 placeholders; quoting numbers when hand-authoring JSON; float artifacts from generators computing issue offsets.
Related errors
- tracking_issue must be a positive integer
- duplicate issue #${agent.issue}
- branch issue segment "${m[2]}" does not match agent issue ${
- batch_id must be a kebab-case slug
- base_repo must be "tinyhumansai/openhuman" (got "${spec.base
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/abbcd37d62d00935.
Report an issue: GitHub.