{"record":{"id":"b29781c2410a7c71","repo":"abhigyanpatwari/GitNexus","slug":"duplicate-analysis-feature-descriptor-descripto","errorCode":null,"errorMessage":"Duplicate analysis feature descriptor: ${descriptor.id}","messagePattern":"Duplicate analysis feature descriptor: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analysis-features.ts","lineNumber":38,"sourceCode":"\n/** Resolve the exact feature set this build promises for the supplied files. */\nexport function resolveAnalysisFeatureVersions(\n  descriptors: readonly AnalysisFeatureDescriptor[],\n  filePaths: readonly string[],\n): Record<string, number> {\n  const resolved = new Map<string, number>();\n  const seenIds = new Set<string>();\n  for (const descriptor of descriptors) {\n    if (descriptor.id.trim().length === 0) {\n      throw new Error('Analysis feature descriptor id must not be empty');\n    }\n    if (!Number.isSafeInteger(descriptor.version) || descriptor.version < 1) {\n      throw new Error(\n        `Analysis feature \"${descriptor.id}\" has invalid version ${descriptor.version}`,\n      );\n    }\n    if (seenIds.has(descriptor.id)) {\n      throw new Error(`Duplicate analysis feature descriptor: ${descriptor.id}`);\n    }\n    seenIds.add(descriptor.id);\n    if (!descriptor.appliesTo(filePaths)) continue;\n    resolved.set(descriptor.id, descriptor.version);\n  }\n\n  return Object.fromEntries([...resolved].sort(([left], [right]) => left.localeCompare(right)));\n}\n\n/**\n * Compare an untrusted metadata value with the exact capabilities produced by\n * this build. Extra keys also mismatch: a rollback must rebuild instead of\n * certifying graph semantics emitted only by a newer binary.\n */\nexport function findAnalysisFeatureMismatches(\n  actual: unknown,\n  expected: AnalysisFeatureVersions,\n): readonly string[] {","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/analysis-features.ts#L20-L56","documentation":"`resolveAnalysisFeatureVersions` encountered two `AnalysisFeatureDescriptor` entries with the same `id`. The feature registry requires unique ids because the id is the key stamped into index metadata and compared during rebuild detection. Duplicate ids would make rollback/mismatch detection ambiguous.","triggerScenarios":"Registering the same feature descriptor object twice, or two new descriptors that happen to share an id string (e.g. both start with 'graph.').","commonSituations":"A refactor that split a descriptor module but accidentally kept both the old and new registration; copy-paste of a descriptor without changing the id; merging two feature branches that each added a colliding id.","solutions":["Remove the duplicate registration so each id appears exactly once.","If both features are legitimate, give each a distinct namespaced id.","Add a unit test asserting the descriptor list has unique ids."],"exampleFix":"// before\n[{ id: 'graph.x', version: 1, appliesTo: () => true },\n { id: 'graph.x', version: 2, appliesTo: () => true }]\n// after\n[{ id: 'graph.x', version: 2, appliesTo: () => true },\n { id: 'graph.y', version: 1, appliesTo: () => true }]","handlingStrategy":"validation","validationCode":"const ids = new Set();\nfor (const d of descriptors) {\n  if (ids.has(d.id)) throw new Error('Duplicate analysis feature: ' + d.id);\n  ids.add(d.id);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single registry of descriptors to avoid duplicate registrations across modules.","Use distinct namespaced ids so merges cannot collide."],"tags":["analysis-features","internal","validation","duplicates"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}