abhigyanpatwari/GitNexus · warning
[group] skipping corrupt crossLinks row in contracts.json
Error message
[group] skipping corrupt crossLinks row in contracts.json
What it means
Emitted while resiliently loading a group's contracts.json: a row of the crossLinks array failed the isCrossLink shape check — from and to must be objects each carrying a string repo, plus string contractId and type. The row is counted in skippedCorrupt and dropped; remaining crossLinks and contracts load normally.
Source
Thrown at gitnexus/src/core/group/service.ts:331
skippedCorrupt++;
logger.warn('[group] skipping corrupt contract row in contracts.json');
}
} catch {
skippedCorrupt++;
logger.warn('[group] skipping corrupt contract row in contracts.json');
}
}
}
const crossLinks: CrossLink[] = [];
if (Array.isArray(crossRaw)) {
for (const row of crossRaw) {
try {
if (isCrossLink(row)) {
crossLinks.push(row);
} else {
skippedCorrupt++;
logger.warn('[group] skipping corrupt crossLinks row in contracts.json');
}
} catch {
skippedCorrupt++;
logger.warn('[group] skipping corrupt crossLinks row in contracts.json');
}
}
}
// Bound once: the gate is a full array scan and the ternary below used it twice.
const recordedUnreadable = recordedRepoList(base.unreadableRepos);
const recordedSuppressed = recordedMatchStages(base.suppressedMatchStages);
// Present-but-unreadable is NOT the same as absent. `recordedMatchStages` is
// all-or-nothing, so garbage collapses to `undefined` — and a consumer that
// reads `undefined` as "nothing was suppressed" would throw that safety away
// and report a registry it could not parse as complete. Absent stays
// legitimate (a registry predating the field); only a value that was there
// and unreadable forces the answer to a floor.
const suppressionUnreadable =View on GitHub (pinned to 52924ef12c)
Solutions
- Re-run group sync to regenerate contracts.json
- Delete the group's contracts.json and re-analyze if the warning persists
- Align any external writer with the CrossLink shape: { contractId: string, type: string, from: { repo: string, ... }, to: { repo: string, ... } }
Example fix
// before — crossLinks row missing `to`
{ "crossLinks": [ { "contractId": "c1", "type": "http", "from": { "repo": "api" } } ] }
// after — both endpoints present
{ "crossLinks": [ { "contractId": "c1", "type": "http",
"from": { "repo": "api", "symbolUid": "u1" },
"to": { "repo": "web", "symbolUid": "u2" } } ] } Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-flight: validate crossLinks rows before the registry loads
import { readFileSync } from 'node:fs';
const registry = JSON.parse(readFileSync('contracts.json', 'utf8'));
const bad = (registry.crossLinks ?? []).filter((r: unknown) => !isCrossLink(r));
if (bad.length > 0) {
throw new Error(`${bad.length} crossLinks row(s) failed the CrossLink shape — regenerate via group sync`);
} Type guard
function isCrossLink(raw: unknown): raw is CrossLink {
if (!raw || typeof raw !== 'object') return false;
const o = raw as Record<string, unknown>;
const from = o.from as Record<string, unknown> | undefined;
const to = o.to as Record<string, unknown> | undefined;
if (!from || !to) return false;
if (typeof from.repo !== 'string' || typeof to.repo !== 'string') return false;
return typeof o.contractId === 'string' && typeof o.type === 'string';
} Prevention
- Let group sync own the full lifecycle of contracts.json including crossLinks
- Do not append link rows from ad-hoc scripts without validating the from/to/contractId/type shape
- Re-run group sync after upgrading GitNexus so crossLinks match the current schema
When it happens
Trigger: A crossLinks row is missing from/to, has a non-string repo, or lacks contractId/type — typically a partially written contracts.json after a crashed sync, a hand edit, or schema drift between GitNexus versions.
Common situations: Interrupted group_sync; manual edits to contracts.json; cross-language or third-party tooling writing links in an older format.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- [group] skipping corrupt contract row in contracts.json
- [group/sync] manifest link ${link.type}:${link.contract} ref
- Bridge query prepare failed: ${errMsg}
- Invalid YAML: expected an object
- version is required in group.yaml
AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20).
Data as JSON: /api/errors/e514f6f114a37673.
Report an issue: GitHub.