tinyhumansai/openhuman · error · SpecError
owned_paths must be a non-empty array
Error message
owned_paths must be a non-empty array
What it means
agent.owned_paths must be a non-empty Array — these are the directory prefixes the agent is allowed to write, and the input to findOverlaps() for disjointness checking downstream. An agent owning nothing is meaningless, so empty arrays (or non-arrays) are rejected before element validation. Path is "agents[i].owned_paths".
Source
Thrown at scripts/agent-batch/lib.mjs:140
}
if (m[1] !== agent.id) {
throw new SpecError(
`branch id segment "${m[1]}" does not match agent id "${agent.id}"`,
`${at}.branch`,
);
}
if (Number(m[2]) !== agent.issue) {
throw new SpecError(
`branch issue segment "${m[2]}" does not match agent issue ${agent.issue}`,
`${at}.branch`,
);
}
if (seenBranch.has(agent.branch)) {
throw new SpecError(`duplicate branch "${agent.branch}"`, `${at}.branch`);
}
seenBranch.add(agent.branch);
if (!Array.isArray(agent.owned_paths) || agent.owned_paths.length === 0) {
throw new SpecError(
"owned_paths must be a non-empty array",
`${at}.owned_paths`,
);
}
for (let j = 0; j < agent.owned_paths.length; j++) {
const p = agent.owned_paths[j];
if (typeof p !== "string" || p.length === 0) {
throw new SpecError(
"must be a non-empty string",
`${at}.owned_paths[${j}]`,
);
}
if (p.includes("*") || p.includes("?")) {
throw new SpecError(
`globs not allowed — use directory prefixes (got "${p}")`,
`${at}.owned_paths[${j}]`,
);
}View on GitHub (pinned to a221052e0d)
Solutions
- List at least one repo-relative directory prefix covering the agent's changes, e.g. ["scripts/ci/"]
- Wrap single paths in an array: "src/" → ["src/"]
- If unsure of scope, give the owning domain directory (one of src/openhuman/<domain>/)
Example fix
// before "owned_paths": [] // after "owned_paths": ["scripts/ci/", ".github/workflows/"]
Defensive patterns
Strategy: validation
Validate before calling
for (const [i, a] of spec.agents.entries()) {
if (!Array.isArray(a.owned_paths) || a.owned_paths.length === 0) {
console.error(`agents[${i}].owned_paths must be a non-empty array`);
process.exit(1);
}
} Type guard
/** @param {unknown} v */
function isNonEmptyStringArray(v) {
return Array.isArray(v) && v.length > 0 && v.every((p) => typeof p === "string" && p.length > 0);
} Try / catch
try {
validateSpec(spec);
} catch (e) {
if (e instanceof SpecError && e.path?.endsWith(".owned_paths")) {
console.error(`scope the agent to at least one directory prefix: ${e.message}`);
process.exit(1);
}
throw e;
} Prevention
- Decide file ownership during slicing, before writing the spec
- Own the deepest directory that covers the changes; arrays can hold several prefixes
When it happens
Trigger: "owned_paths": [], "owned_paths": "src/", "owned_paths": {"src": true}, or null on an agent entry.
Common situations: Omitting scope decisions until later and leaving an empty list; putting a single string instead of a one-element array; generator defaulting to [] when it could not map the work to paths.
Related errors
- must be a non-empty string
- globs not allowed — use directory prefixes (got "${p}")
- batch_id must be a kebab-case slug
- base_repo must be "tinyhumansai/openhuman" (got "${spec.base
- base_branch must be "main" (got "${spec.base_branch}")
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/25f9907d3e496957.
Report an issue: GitHub.