{"record":{"id":"e99e6c8821afd862","repo":"abhigyanpatwari/GitNexus","slug":"analysis-feature-descriptor-id-must-not-be-empty","errorCode":null,"errorMessage":"Analysis feature descriptor id must not be empty","messagePattern":"Analysis feature descriptor id must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/core/analysis-features.ts","lineNumber":30,"sourceCode":" * Existing v8 indexes predate the frameworkAnnotations column and therefore\n * need one full rebuild before any incremental Class write can be safe.\n */\nexport 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/**","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/core/analysis-features.ts#L12-L48","documentation":"`resolveAnalysisFeatureVersions` iterated an `AnalysisFeatureDescriptor` whose `id` is empty or whitespace-only after trimming. Descriptors are code constants (not user input), so this is a programmer/build-time defect: a feature was registered without naming it. Each descriptor's id is part of the durable rebuild-vs-incremental contract stamped into index metadata.","triggerScenarios":"Registering a descriptor like { id: '', version: 1, appliesTo: () => true } or { id: '   ', version: 1, ... } in the feature registry passed to `resolveAnalysisFeatureVersions`.","commonSituations":"Adding a new analysis feature descriptor and forgetting to set the id string; refactor that left a placeholder id; copy-paste of a descriptor template without filling the id.","solutions":["Give the descriptor a non-empty, trimmed id, e.g. 'graph.class-framework-annotations'.","Use a stable namespaced id so it does not collide with other features.","Add a unit test asserting every registered descriptor has a non-empty id."],"exampleFix":"// before\n{ id: '', version: 1, appliesTo: () => true }\n// after\n{ id: 'graph.my-feature', version: 1, appliesTo: () => true }","handlingStrategy":"validation","validationCode":"function assertDescriptorsWellFormed(descriptors) {\n  for (const d of descriptors) {\n    if (typeof d.id !== 'string' || d.id.trim().length === 0) {\n      throw new Error('descriptor id must not be empty');\n    }\n  }\n}","typeGuard":"const hasNonEmptyId = (d) =>\n  typeof d.id === 'string' && d.id.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Always set a stable, namespaced id when authoring a descriptor.","Add a unit test that every registered descriptor passes the id/version/duplicate checks."],"tags":["analysis-features","internal","validation"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}