Skip to content

Destructured object-pattern bindings (const { x: renamed } = fn()) misclassified as kind=function, causing false dead-unresolved flags #1773

Description

@carlos-alm

Summary

The JS/TS extractor classifies destructured object-pattern binding targets (including renamed bindings, e.g. const { values: flags } = parseArgs(...)) as kind: "function" instead of kind: "variable"/"constant". Because these bindings have no call-graph edges pointing at them by name, codegraph roles --role dead then flags them as dead-unresolved even when they are read repeatedly elsewhere in the file.

This is distinct from #1723 (which covers kind: parameter and interface/type member false positives) — the root cause here is extractor-level miscategorization of destructuring-pattern declarations, not the dead-code classifier's zero-fan-in heuristic on parameters.

Repro

$ codegraph roles --role dead --file scripts/token-benchmark.ts -T --json

scripts/token-benchmark.ts:42:

const { values: flags } = parseArgs({
  options: { runs: { type: 'string', default: '3' }, /* ... */ },
  strict: false,
});

flags is reported as kind: "function", role: "dead-unresolved", totalDependents: 0, despite being read 8+ times later in the same file (flags.runs, flags.model, flags['max-turns'], flags['nextjs-dir'], etc. at lines 56-64 and 531-532).

Also reproduces with non-renamed destructuring:

// tests/unit/snapshot-race-worker.mjs:13
const { dbPath, name, force } = workerData;

codegraph deps/codegraph where report dbPath, name, and force all as kind: "function" at line 13, and force is flagged dead-unresolved by the dead-code classifier.

Impact

Any top-level or block-scoped destructured binding (renamed or not) risks a false dead-unresolved classification, and more generally the kind metadata for these bindings is wrong (function instead of variable/constant), which pollutes any query filtering by kind.

Suggested fix

In the JS/TS extractor, object-pattern destructuring targets (ObjectPattern / ShorthandPropertyIdentifierPattern / PairPattern value nodes) should be extracted with kind: "variable" (or constant" when declared via const), not kind: "function". The dead-code classifier should then treat these like any other variable binding for reference counting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions