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

  1. Re-run group sync to regenerate contracts.json
  2. Delete the group's contracts.json and re-analyze if the warning persists
  3. 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

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


AI-assisted analysis of abhigyanpatwari/GitNexus@52924ef12c (2026-08-20). Data as JSON: /api/errors/e514f6f114a37673. Report an issue: GitHub.