Skip to content

fix(native): widen NativeRepository file filters to accept string[]#1959

Open
carlos-alm wants to merge 1 commit into
fix/issue-1813-import-type-x-inline-per-specifier-modifierfrom
fix/issue-1815-same-f-file-array-vs-string-native-crash
Open

fix(native): widen NativeRepository file filters to accept string[]#1959
carlos-alm wants to merge 1 commit into
fix/issue-1813-import-type-x-inline-per-specifier-modifierfrom
fix/issue-1815-same-f-file-array-vs-string-native-crash

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

  • triage -f/-f -f silently swallowed a fatal napi-rs type-conversion error into an empty result at exit code 0, because -f (via collectFile) always produces a string[], but find_nodes_for_triage in crates/codegraph-core/src/db/repository/graph_read.rs was typed for a single String. This is the same bug class fixed for fn-impact/query in codegraph fn-impact and query crash with fatal native error when -f/--file is passed #1726/fix: prevent fn-impact/query crash when -f/--file is passed #1816.
  • The same pattern existed in three other NativeRepository methods with no CLI caller today (find_nodes_by_scope, find_node_by_qualified_name, list_function_nodes/iterate_function_nodes) — fixed for architectural consistency so any future CLI wiring doesn't reintroduce this crash.
  • interfaces/implementations (also named in Same -f/--file array-vs-String native crash affects triage, interfaces, implementations, and other NativeRepository methods #1815) turned out to already be fixed as a side effect of fix: prevent fn-impact/query crash when -f/--file is passed #1816 landing, since both route through findMatchingNodesfindNodesWithFanIn, whose native binding was widened to Vec<String> in that PR. Verified via a live repro that they no longer crash.
  • Widened the five affected NativeDatabase bindings (Rust + TS declarations) to Option<Vec<String>>/string[], reusing the push_file_filter() helper already shared by find_nodes_with_fan_in/fn_deps, and updated NativeRepository to forward the full normalized array instead of truncating to the first value (previously the case for findNodesByScope).
  • Fixed features/triage.ts's silent catch-and-return-empty: it now only degrades gracefully for the validated-input ConfigError case (invalid --kind/--role, relevant to the MCP triage tool which doesn't pre-validate); any other failure (e.g. an internal query bug) now propagates instead of masquerading as "no symbols match" at exit 0.

Test plan

  • npm test — full suite green (3722 passed, 30 skipped, 2 todo)
  • npm run lint / tsc --noEmit — clean
  • Native addon rebuilt and codesigned locally; verified via before/after cycle: reverted the Rust fix, rebuilt, confirmed triage -f reproduces the exact reported bug (Failed to convert JavaScript value \Object ["src/math.js"]` into rust type `String`swallowed into{"items":[],...}at exit 0); restored the fix, rebuilt, confirmedtriage -fand repeated-f -f` return correct non-empty, correctly-scoped results
  • Cross-checked native vs CODEGRAPH_ENGINE=wasm on multi-file triage -f -f — identical items/scores (dual-engine parity)
  • New regression tests: tests/integration/cli.test.ts (triage -f/-f -f end-to-end via the real CLI binary, plus smoke tests for interfaces -f/implementations -f) and tests/integration/triage.test.ts (ConfigError-only catch behavior)

Fixes #1815

Stacked on #1958 (base branch fix/issue-1813-import-type-x-inline-per-specifier-modifier) — only the graph_read.rs/repository/triage/test diff is this issue's change.

triage, and the unwired findNodesByScope/findNodeByQualifiedName/
listFunctionNodes/iterateFunctionNodes native bindings, forwarded the
CLI's repeatable -f/--file array straight into rusqlite bindings typed
for a single Rust String. triage silently swallowed the resulting
napi-rs conversion error into an empty result at exit code 0; the
others would crash the same way once wired up.

Widen the five NativeDatabase bindings (Rust + TS declarations) to
Option<Vec<String>>, reusing the push_file_filter() helper already
shared by find_nodes_with_fan_in/fn_deps, and forward the full
normalized array from NativeRepository instead of truncating to the
first value. Also narrow triageData's catch to only swallow the
validated-input ConfigError case so a genuine internal failure
propagates instead of masquerading as "no symbols match".

Impact: 24 functions changed, 46 affected
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a silent napi-rs type-conversion crash where -f/--file (a repeatable Commander option that always produces string[]) was being forwarded to five native bindings typed for a single String, causing the error to be swallowed into an empty result at exit 0. It also narrows the triage catch block to only degrade gracefully for ConfigError (invalid --kind/--role), letting all other internal failures propagate.

  • Rust: build_triage_query, find_nodes_by_scope, find_node_by_qualified_name, list_function_nodes/iterate_function_nodes all widened from Option<String> to Option<Vec<String>>, reusing the existing push_file_filter() helper.
  • TypeScript: All three repository implementations and the NativeDatabase declaration updated consistently; ListFunctionOpts, TriageQueryOpts, and findNodeByQualifiedName opts widened to string | string[].
  • Tests: New regression tests cover the triage -f/-f -f end-to-end CLI paths, the ConfigError-only graceful-degradation contract, and interfaces/implementations -f smoke tests.

Confidence Score: 5/5

Safe to merge. The change is a targeted type-widening fix with consistent application across all three repository backends, reuses a well-tested SQL helper, and is covered by new end-to-end and unit regression tests.

The fix is mechanically straightforward — every affected native binding now receives an array and delegates to push_file_filter(), which already drives the multi-value LIKE clause used by other bindings since #1726/#1816. The TypeScript side uniformly uses normalizeFileFilter() before passing to napi. The catch-block narrowing is safe: ConfigError is the only validation-input failure that should produce an empty graceful result, and the new tests directly assert both the propagation and degradation paths. No cross-cutting regressions are expected.

No files require special attention. The Rust changes in graph_read.rs are the most impactful, but the logic is consistent with the existing push_file_filter pattern.

Important Files Changed

Filename Overview
crates/codegraph-core/src/db/repository/graph_read.rs Five napi bindings widened from Option/Option to Option<Vec>/Option<&[String]>, all delegating to the existing push_file_filter() helper. Logic is consistent and correct across build_triage_query, find_nodes_by_scope, find_node_by_qualified_name, query_function_nodes.
src/db/repository/native-repository.ts All five NativeRepository methods now call normalizeFileFilter() and pass string[] (or null) to the widened napi bindings; replaces the old findNodesByScope truncation and the bare opts.file pass-through for the others.
src/features/triage.ts catch block narrowed to only swallow ConfigError; all other errors now re-throw, preventing silent masking of internal query failures as empty results at exit 0.
src/types.ts NativeDatabase TS declaration updated to match widened Rust signatures; ListFunctionOpts and TriageQueryOpts file fields widened to string
tests/integration/triage.test.ts New regression tests verify propagation of non-ConfigError failures and graceful degradation for ConfigError only — directly covers the behavioral change in features/triage.ts.
tests/integration/cli.test.ts End-to-end CLI tests added for triage -f, triage -f -f (multi-file), and interfaces/implementations -f smoke tests covering the exact bug reported in #1815.
src/db/repository/in-memory-repository.ts findNodeByQualifiedName signature updated to accept string
src/db/repository/nodes.ts findNodeByQualifiedName opts widened to string
src/db/repository/sqlite-repository.ts findNodeByQualifiedName signature updated to match widened interface, passing through to nodes.ts which handles multi-value file filters.
src/db/repository/base.ts Base class stub updated to reflect widened signature; no logic changes.
src/domain/analysis/implementations.ts implementationsData and interfacesData opts.file widened to string
src/presentation/triage.ts TriageOpts.file widened to string

Reviews (1): Last reviewed commit: "fix(native): widen NativeRepository file..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

26 functions changed24 callers affected across 17 files

  • Repository in src/db/repository/base.ts:28 (0 transitive callers)
  • Repository.findNodeByQualifiedName in src/db/repository/base.ts:78 (0 transitive callers)
  • InMemoryRepository in src/db/repository/in-memory-repository.ts:73 (1 transitive callers)
  • InMemoryRepository.findNodeByQualifiedName in src/db/repository/in-memory-repository.ts:270 (0 transitive callers)
  • NativeRepository in src/db/repository/native-repository.ts:224 (3 transitive callers)
  • NativeRepository.findNodesByScope in src/db/repository/native-repository.ts:305 (0 transitive callers)
  • NativeRepository.findNodeByQualifiedName in src/db/repository/native-repository.ts:312 (0 transitive callers)
  • NativeRepository.listFunctionNodes in src/db/repository/native-repository.ts:322 (0 transitive callers)
  • NativeRepository.iterateFunctionNodes in src/db/repository/native-repository.ts:333 (0 transitive callers)
  • NativeRepository.findNodesForTriage in src/db/repository/native-repository.ts:345 (0 transitive callers)
  • findNodeByQualifiedName in src/db/repository/nodes.ts:324 (1 transitive callers)
  • SqliteRepository in src/db/repository/sqlite-repository.ts:68 (13 transitive callers)
  • SqliteRepository.findNodeByQualifiedName in src/db/repository/sqlite-repository.ts:131 (0 transitive callers)
  • implementationsData in src/domain/analysis/implementations.ts:12 (2 transitive callers)
  • interfacesData in src/domain/analysis/implementations.ts:55 (2 transitive callers)
  • TriageDataOpts.file in src/features/triage.ts:112 (0 transitive callers)
  • triageData in src/features/triage.ts:147 (3 transitive callers)
  • TriageOpts.file in src/presentation/triage.ts:13 (0 transitive callers)
  • ListFunctionOpts.file in src/types.ts:276 (0 transitive callers)
  • TriageQueryOpts.file in src/types.ts:287 (0 transitive callers)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant