abhigyanpatwari/GitNexus · error · Error
repos is required in group.yaml (must be a mapping)
Error message
repos is required in group.yaml (must be a mapping)
What it means
Thrown by parseGroupConfig when the 'repos' field is missing, null, not an object, or an array. repos must be a YAML mapping of repo-path strings (the keys become the valid set of endpoints for link.from/link.to). This check runs before links are validated so that the repoPaths set is well-defined.
Source
Thrown at gitnexus/src/core/group/config-parser.ts:59
max_candidates_per_step: 3,
exclude_links_paths: [] as string[],
exclude_links_param_only_paths: false,
};
export function parseGroupConfig(yamlContent: string): GroupConfig {
const raw = yaml.load(yamlContent, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
throw new Error('Invalid YAML: expected an object');
}
if (raw.version === undefined) throw new Error('version is required in group.yaml');
if (raw.version !== 1) {
throw new Error(`Unsupported group.yaml version: ${raw.version}. Expected 1.`);
}
if (!raw.name || typeof raw.name !== 'string') throw new Error('name is required in group.yaml');
if (!raw.repos || typeof raw.repos !== 'object' || Array.isArray(raw.repos)) {
throw new Error('repos is required in group.yaml (must be a mapping)');
}
const repos = raw.repos as Record<string, string>;
const repoPaths = new Set(Object.keys(repos));
const rawLinks = (raw.links as unknown[]) || [];
const links: GroupManifestLink[] = rawLinks.map((l: unknown, i: number) => {
const link = l as Record<string, unknown>;
if (!link.from || !repoPaths.has(link.from as string)) {
throw new Error(`links[${i}].from "${link.from}" does not match any repo path in group`);
}
if (!link.to || !repoPaths.has(link.to as string)) {
throw new Error(`links[${i}].to "${link.to}" does not match any repo path in group`);
}
if (!VALID_CONTRACT_TYPES.includes(link.type as ContractType)) {
throw new Error(
`links[${i}].type "${link.type}" is invalid. Expected: ${VALID_CONTRACT_TYPES.join(', ')}`,
);View on GitHub (pinned to d540b00184)
Solutions
- Make 'repos' a YAML mapping. The keys are the repo paths used in links; values are the local checkout paths.
- If you have no repos yet, write `repos: {}` (empty mapping) rather than omitting the key or using an array.
Example fix
# before — array, rejected repos: - ./services/api - ./services/worker # after — mapping repos: ./services/api: ./services/api ./services/worker: ./services/worker
Defensive patterns
Strategy: validation
Validate before calling
const raw = yaml.load(text, { schema: yaml.JSON_SCHEMA }) as Record<string, unknown>;
if (raw.repos === null || typeof raw.repos !== 'object' || Array.isArray(raw.repos)) {
throw new Error('group.yaml requires repos as a mapping of path -> checkout path');
} Type guard
function isReposMapping(v: unknown): v is Record<string, string> {
return v !== null && typeof v === 'object' && !Array.isArray(v);
} Prevention
- Use a YAML mapping for repos, not an array — `repos: { './a': './a' }`.
- When empty, write `repos: {}` explicitly.
- Document the mapping-vs-list distinction in any group authoring guide.
When it happens
Trigger: group.yaml with no 'repos' key; repos set to a YAML array; repos set to a scalar; repos present but null.
Common situations: A manifest that lists repos as an array (e.g. `repos: [./a, ./b]`) instead of a mapping (e.g. `repos: { './a': ./a }`); a template where repos was emptied and the braces removed; misreading the schema docs.
Related errors
- Invalid YAML: expected an object
- version is required in group.yaml
- name is required in group.yaml
- links[${i}].from "${link.from}" does not match any repo path
- links[${i}].to "${link.to}" does not match any repo path in
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/f5b458fedc02b502.
Report an issue: GitHub.