abhigyanpatwari/GitNexus · error · Error
links[${i}].role "${link.role}" is invalid. Expected: provid
Error message
links[${i}].role "${link.role}" is invalid. Expected: provider | consumer What it means
Thrown during links[] validation when a link's 'role' field is not 'provider' or 'consumer'. VALID_ROLES is a closed two-value enum describing which side of the contract the 'from' repo plays. The message restates both allowed values.
Source
Thrown at gitnexus/src/core/group/config-parser.ts:80
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(', ')}`,
);
}
if (!VALID_ROLES.includes(link.role as ContractRole)) {
throw new Error(`links[${i}].role "${link.role}" is invalid. Expected: provider | consumer`);
}
if (
link.contract === undefined ||
link.contract === null ||
String(link.contract).trim() === ''
) {
throw new Error(`links[${i}].contract is required`);
}
return {
from: link.from as string,
to: link.to as string,
type: link.type as ContractType,
contract: String(link.contract),
role: link.role as ContractRole,
};
});
const detect = { ...DEFAULT_DETECT, ...((raw.detect as object) || {}) };View on GitHub (pinned to d540b00184)
Solutions
- Set link.role to exactly 'provider' or 'consumer' (lowercase).
- Use 'provider' when the 'from' repo exposes the contract; 'consumer' when it calls it.
Example fix
# before — synonym + wrong case
links:
- { from: services/api, to: services/worker, type: http, contract: GET /v1, role: Server }
# after
links:
- { from: services/api, to: services/worker, type: http, contract: GET /v1, role: provider } Defensive patterns
Strategy: type-guard
Validate before calling
const VALID_ROLES = ['provider','consumer'] as const;
type ContractRole = typeof VALID_ROLES[number];
function isContractRole(v: unknown): v is ContractRole {
return typeof v === 'string' && (VALID_ROLES as readonly string[]).includes(v);
} Type guard
function isContractRole(v: unknown): v is ContractRole {
return v === 'provider' || v === 'consumer';
} Prevention
- Use 'provider' or 'consumer' verbatim — never synonyms like server/client.
- Add a JSON Schema enum for role to enable editor autocompletion.
- Cross-check role semantics: provider exposes the contract; consumer calls it.
When it happens
Trigger: A link with role: 'Provider' (wrong case), role: 'server', role: 'client', role: 'producer', or a missing role field.
Common situations: Wrong-case typo; using a synonym (server/client, producer/subscriber) instead of the canonical provider/consumer; missing role in a hand-authored link.
Related errors
- links[${i}].from "${link.from}" does not match any repo path
- links[${i}].to "${link.to}" does not match any repo path in
- links[${i}].type "${link.type}" is invalid. Expected: ${VALI
- links[${i}].contract is required
- Invalid YAML: expected an object
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/e91e656f3b94edcb.
Report an issue: GitHub.