abhigyanpatwari/GitNexus · warning
property-dispatch: keys over the fan-out cap were dropped (n
Error message
property-dispatch: keys over the fan-out cap were dropped (no CALLS synthesized for them)
What it means
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.
Source
Thrown at gitnexus/src/core/ingestion/scope-resolution/pipeline/run.ts:1219
// functions registered under the same property key. This runs after the
// ordinary precise passes but before callable-value-flow: property-dispatched
// wrapper calls must populate the callee accumulator before actual→formal
// propagation. `graph.addRelationship` remains first-write-wins, so precise
// edges already emitted for a site retain ownership.
const propertyDispatch = callableFlowOnly
? { usesEmitted: 0, callsEmitted: 0, skippedKeys: 0, skippedKeyNames: [] as readonly string[] }
: emitPropertyDispatchCalls(
graph,
indexes,
emitParsedFiles,
postHeritageNodeLookup,
calleeIdAccumulator,
);
if (propertyDispatch.skippedKeys > 0) {
// Never drop dispatch coverage silently: a hook table larger than the
// fan-out cap means member calls through those keys get no synthesized
// CALLS — the #2437 false-safe gap reappears for exactly those keys.
logger.warn(
{
lang: provider.language,
skippedKeys: propertyDispatch.skippedKeys,
skippedKeyNames: propertyDispatch.skippedKeyNames,
fanoutCap: MAX_PROPERTY_DISPATCH_FANOUT,
},
'property-dispatch: keys over the fan-out cap were dropped (no CALLS synthesized for them)',
);
}
const callableValueFlow =
calleeIdAccumulator === undefined
? {
emitted: 0,
resolvedInvokes: 0,
ambiguousInvokes: 0,
unmatchedInvokes: 0,
iterations: 0,
}View on GitHub (pinned to 0d1aed942f)
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
Example fix
# before export GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT= # unset → default 32, warn fires npx gitnexus analyze # after export GITNEXUS_MAX_PROPERTY_DISPATCH_FANOUT=64 npx gitnexus analyze # key's synthesized CALLS emitted again
Defensive patterns
Strategy: validation
Validate before calling
// Fail CI when property-dispatch keys were dropped:
const out = runAnalyzeCaptureStderr();
if (/property-dispatch: keys over the fan-out cap/.test(out)) {
const keys = JSON.parse(out.match(/skippedKeyNames[^\]]*\]/)[0]); // inspect dropped keys
process.exitCode = 1;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- callable-value-flow: candidate set exceeded the cap; no part
- interface-dispatch: members over the fan-out cap dropped imp
- ${name} must be a positive integer, got "${raw}"
- ${name} must be a positive integer <= ${max}, got "${raw}"
- ${name} must be a non-negative integer, got "${raw}"
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20).
Data as JSON: /api/errors/f8b247b28d650f42.
Report an issue: GitHub.