{"record":{"id":"02e3b47b8cc2e9f2","repo":"abhigyanpatwari/GitNexus","slug":"analysis-feature-descriptor-id-has-invalid-ve","errorCode":null,"errorMessage":"Analysis feature \"${descriptor.id}\" has invalid version ${descriptor.version}","messagePattern":"Analysis feature \"(.+?)\" has invalid version (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analysis-features.ts","lineNumber":33,"sourceCode":"export const CLASS_FRAMEWORK_ANNOTATIONS_FEATURE: AnalysisFeatureDescriptor = {\n  id: 'graph.class-framework-annotations',\n  version: 1,\n  appliesTo: () => true,\n};\n\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.","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/analysis-features.ts#L15-L51","documentation":"An `AnalysisFeatureDescriptor`'s `version` is not a safe positive integer: it is NaN, fractional, zero, negative, or beyond Number.MAX_SAFE_INTEGER. Versions are part of the rebuild-vs-incremental contract — when a feature's output semantics change, the version is bumped so older indexes are detected as needing a rebuild.","triggerScenarios":"Registering { id: 'graph.x', version: 0, ... }, version: 1.5, or version: -1.","commonSituations":"Starting version numbering at 0 instead of 1; using a semantic-version float like 1.2; computing the version from an expression that can yield NaN.","solutions":["Set `version` to an integer >= 1.","Bump the integer (2, 3, ...) whenever the feature's emitted graph semantics change.","Keep versions as literal integers in the descriptor, never computed from floats."],"exampleFix":"// before\n{ id: 'graph.x', version: 0, appliesTo: () => true }\n// after\n{ id: 'graph.x', version: 1, appliesTo: () => true }","handlingStrategy":"validation","validationCode":"for (const d of descriptors) {\n  if (!Number.isSafeInteger(d.version) || d.version < 1) {\n    throw new Error('feature \"' + d.id + '\" has invalid version ' + d.version);\n  }\n}","typeGuard":"const hasValidVersion = (d) =>\n  Number.isSafeInteger(d.version) && d.version >= 1;","tryCatchPattern":null,"preventionTips":["Use literal integer versions starting at 1.","Bump the version whenever the feature's emitted graph semantics change."],"tags":["analysis-features","internal","validation","versioning"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}