{"record":{"id":"f8b247b28d650f42","repo":"abhigyanpatwari/GitNexus","slug":"property-dispatch-keys-over-the-fan-out-cap-were","errorCode":null,"errorMessage":"property-dispatch: keys over the fan-out cap were dropped (no CALLS synthesized for them)","messagePattern":"property-dispatch: keys over the fan-out cap were dropped \\(no CALLS synthesized for them\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/ingestion/scope-resolution/pipeline/run.ts","lineNumber":1219,"sourceCode":"  // functions registered under the same property key. This runs after the\n  // ordinary precise passes but before callable-value-flow: property-dispatched\n  // wrapper calls must populate the callee accumulator before actual→formal\n  // propagation. `graph.addRelationship` remains first-write-wins, so precise\n  // edges already emitted for a site retain ownership.\n  const propertyDispatch = callableFlowOnly\n    ? { usesEmitted: 0, callsEmitted: 0, skippedKeys: 0, skippedKeyNames: [] as readonly string[] }\n    : emitPropertyDispatchCalls(\n        graph,\n        indexes,\n        emitParsedFiles,\n        postHeritageNodeLookup,\n        calleeIdAccumulator,\n      );\n  if (propertyDispatch.skippedKeys > 0) {\n    // Never drop dispatch coverage silently: a hook table larger than the\n    // fan-out cap means member calls through those keys get no synthesized\n    // CALLS — the #2437 false-safe gap reappears for exactly those keys.\n    logger.warn(\n      {\n        lang: provider.language,\n        skippedKeys: propertyDispatch.skippedKeys,\n        skippedKeyNames: propertyDispatch.skippedKeyNames,\n        fanoutCap: MAX_PROPERTY_DISPATCH_FANOUT,\n      },\n      'property-dispatch: keys over the fan-out cap were dropped (no CALLS synthesized for them)',\n    );\n  }\n  const callableValueFlow =\n    calleeIdAccumulator === undefined\n      ? {\n          emitted: 0,\n          resolvedInvokes: 0,\n          ambiguousInvokes: 0,\n          unmatchedInvokes: 0,\n          iterations: 0,\n        }","sourceCodeStart":1201,"sourceCodeEnd":1237,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/0d1aed942f0e8b5d3bac27519fff441aceea722d/gitnexus/src/core/ingestion/scope-resolution/pipeline/run.ts#L1201-L1237","documentation":"The property-dispatch pass synthesizes CALLS edges for member calls through property keys registered by a bounded set of functions (hook tables). When a key is registered by more distinct functions than MAX_PROPERTY_DISPATCH_FANOUT (default 32, overridable via GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT), that key is skipped: calls through it get no synthesized CALLS. The warn makes that #2437-style false-safe gap visible instead of silent.","triggerScenarios":"Emit-phase indexing (not callableFlowOnly) of a repo whose property/hook tables register more than 32 functions under one key — emitPropertyDispatchCalls returns skippedKeys > 0 and the orchestrator warns with language, count, key names, and the cap. Large Vue codebases where 'validator' exceeds the default are the documented case.","commonSituations":"Vue component libraries with dozens of validators, central handler registries (event/hook/plugin tables) that grow past 32 registrations per key, or repos where someone lowered the cap env below a legitimately wide table.","solutions":["Set GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT above your widest key's registration count (e.g. 64) and re-run analyze","Read skippedKeyNames from the warn to identify the dropped keys, then confirm calls through those keys now resolve (context() on a consumer site)","If the wide key is uninformative dispatch (a name registered by everything), leave it capped and rely on other edges — dispatch through such a name says little about which function runs","Split the over-wide registry in your own code so each key stays under the cap"],"exampleFix":"# before\nexport GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT=   # unset → default 32, warn fires\nnpx gitnexus analyze\n# after\nexport GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT=64\nnpx gitnexus analyze   # key's synthesized CALLS emitted again","handlingStrategy":"validation","validationCode":"// Fail CI when property-dispatch keys were dropped:\nconst out = runAnalyzeCaptureStderr();\nif (/property-dispatch: keys over the fan-out cap/.test(out)) {\n  const keys = JSON.parse(out.match(/skippedKeyNames[^\\]]*\\]/)[0]); // inspect dropped keys\n  process.exitCode = 1;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep hook-table registrations per key under 32, or set GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT accordingly","Audit analyze logs for 'skippedKeyNames' — each named key silently loses synthesized CALLS","Treat impact() through an over-cap key as UNKNOWN, not unaffected"],"tags":["static-analysis","property-dispatch","calls-edges","graph-coverage","configuration"],"backgroundTag":"result-set-truncation","analyzedSha":"0d1aed942f0e8b5d3bac27519fff441aceea722d","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}