{"record":{"id":"e514f6f114a37673","repo":"abhigyanpatwari/GitNexus","slug":"group-skipping-corrupt-crosslinks-row-in-contrac","errorCode":null,"errorMessage":"[group] skipping corrupt crossLinks row in contracts.json","messagePattern":"\\[group\\] skipping corrupt crossLinks row in contracts\\.json","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/group/service.ts","lineNumber":331,"sourceCode":"          skippedCorrupt++;\n          logger.warn('[group] skipping corrupt contract row in contracts.json');\n        }\n      } catch {\n        skippedCorrupt++;\n        logger.warn('[group] skipping corrupt contract row in contracts.json');\n      }\n    }\n  }\n\n  const crossLinks: CrossLink[] = [];\n  if (Array.isArray(crossRaw)) {\n    for (const row of crossRaw) {\n      try {\n        if (isCrossLink(row)) {\n          crossLinks.push(row);\n        } else {\n          skippedCorrupt++;\n          logger.warn('[group] skipping corrupt crossLinks row in contracts.json');\n        }\n      } catch {\n        skippedCorrupt++;\n        logger.warn('[group] skipping corrupt crossLinks row in contracts.json');\n      }\n    }\n  }\n\n  // Bound once: the gate is a full array scan and the ternary below used it twice.\n  const recordedUnreadable = recordedRepoList(base.unreadableRepos);\n  const recordedSuppressed = recordedMatchStages(base.suppressedMatchStages);\n  // Present-but-unreadable is NOT the same as absent. `recordedMatchStages` is\n  // all-or-nothing, so garbage collapses to `undefined` — and a consumer that\n  // reads `undefined` as \"nothing was suppressed\" would throw that safety away\n  // and report a registry it could not parse as complete. Absent stays\n  // legitimate (a registry predating the field); only a value that was there\n  // and unreadable forces the answer to a floor.\n  const suppressionUnreadable =","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/52924ef12c2290ceee4612526a828ec4cdf2047f/gitnexus/src/core/group/service.ts#L313-L349","documentation":"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.","triggerScenarios":"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.","commonSituations":"Interrupted group_sync; manual edits to contracts.json; cross-language or third-party tooling writing links in an older format.","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, ... } }"],"exampleFix":"// before — crossLinks row missing `to`\n{ \"crossLinks\": [ { \"contractId\": \"c1\", \"type\": \"http\", \"from\": { \"repo\": \"api\" } } ] }\n\n// after — both endpoints present\n{ \"crossLinks\": [ { \"contractId\": \"c1\", \"type\": \"http\",\n    \"from\": { \"repo\": \"api\", \"symbolUid\": \"u1\" },\n    \"to\": { \"repo\": \"web\", \"symbolUid\": \"u2\" } } ] }","handlingStrategy":"type-guard","validationCode":"// Pre-flight: validate crossLinks rows before the registry loads\nimport { readFileSync } from 'node:fs';\nconst registry = JSON.parse(readFileSync('contracts.json', 'utf8'));\nconst bad = (registry.crossLinks ?? []).filter((r: unknown) => !isCrossLink(r));\nif (bad.length > 0) {\n  throw new Error(`${bad.length} crossLinks row(s) failed the CrossLink shape — regenerate via group sync`);\n}","typeGuard":"function isCrossLink(raw: unknown): raw is CrossLink {\n  if (!raw || typeof raw !== 'object') return false;\n  const o = raw as Record<string, unknown>;\n  const from = o.from as Record<string, unknown> | undefined;\n  const to = o.to as Record<string, unknown> | undefined;\n  if (!from || !to) return false;\n  if (typeof from.repo !== 'string' || typeof to.repo !== 'string') return false;\n  return typeof o.contractId === 'string' && typeof o.type === 'string';\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["group","contracts-json","crosslink","schema","corrupt-row"],"backgroundTag":"schema-validation-failed","analyzedSha":"52924ef12c2290ceee4612526a828ec4cdf2047f","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}