Skip to content

fix(search): replace ANY($n) array params with IN-list for Bun.SQL compat - #25

Merged
smart-knowledge-systems merged 2 commits into
mainfrom
fix/bun-sql-any-array
Apr 15, 2026
Merged

smart-knowledge-systems merged 2 commits into
mainfrom
fix/bun-sql-any-array

Conversation

@smart-knowledge-systems

Copy link
Copy Markdown
Owner

Summary

  • Fixes cidx search crash: "number of array dimensions (N) exceeds the maximum allowed (6)" when searching repos with store: pg and useBlobSchema: true
  • Root cause: Bun.SQL.unsafe() misserialises nested JS arrays passed as PG ANY($n) parameters — the repo ID value gets interpreted as array dimensions
  • Replaces ANY($n) with IN(...) interpolation for validated integer repo IDs and individual $n placeholders for file paths in two queries (search-pg.ts, query.ts)

Test plan

  • cidx search "main exports and public API" --include-skeleton --top-n 10 --format pretty from mpp-next (repo_id=101) returns results without error
  • bun run check passes (lint + typecheck)
  • Verify --include-snippet flag also works (exercises the query.ts fix)

🤖 Generated with Claude Code

…mpat

Bun.SQL misserialises nested JavaScript arrays passed as PG ANY($n)
parameters, causing "number of array dimensions (N) exceeds maximum
allowed (6)" when the repo ID is ≥7. Replace with IN-list interpolation
for validated integer repo IDs and individual $n placeholders for file
paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes a Bun.SQL crash ("number of array dimensions exceeds maximum") triggered in the useBlobSchema: true code path by replacing ANY($n) array parameters with IN(...) interpolation for validated integer repo IDs and numbered $n bind parameters for file paths. The same pattern is applied consistently in both search-pg.ts (blob-schema junction lookup) and query.ts (withSnippets skeleton fetch).

Confidence Score: 5/5

Safe to merge; the bug fix is correct and the one edge case flagged is theoretical and doesn't affect any realistic input.

Both changes correctly address the root cause (Bun.SQL nested-array misserialisation) by inlining validated integers and parameterising strings. Repo IDs are validated before interpolation throughout. The only concern is a P2 edge case where an empty resultRepoIds would produce IN () in query.ts — but in practice this path is unreachable because every file result maps to currentRepoId when r.repoId is absent. No P0/P1 issues exist.

src/search/query.ts — add a resultRepoIds.length === 0 early-exit guard to future-proof the IN () edge case.

Important Files Changed

Filename Overview
src/search/search-pg.ts Replaces ANY($1)/ANY($2) with IN(repo_ids) interpolation (validated integers) and IN($1,…,$n) parameterized placeholders for file paths; guarded by the existing junctionRows.length > 0 check so arrays are always non-empty.
src/search/query.ts Applies the same ANY→IN fix for the withSnippets skeleton fetch; resultRepoIds is guarded only by filePaths.length > 0, not by a direct check on its own length, meaning an empty resultRepoIds would produce invalid IN () SQL whereas the old ANY(ARRAY[]) silently returned zero rows.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant searchPg
    participant searchPgInTransaction
    participant BunSQL as Bun.SQL (pg.unsafe)

    Caller->>searchPg: searchPg(repoIds, ..., useBlobSchema=true)
    searchPg->>searchPgInTransaction: withRepoScope → searchPgInTransaction(tx, ...)

    Note over searchPgInTransaction: validate repoIds as integers
    searchPgInTransaction->>BunSQL: buildBlobFileQuery → SELECT from file_blobs JOIN repo_files WHERE repo_id IN (1,2,...)
    BunSQL-->>searchPgInTransaction: junctionRows[]

    alt junctionRows.length > 0
        Note over searchPgInTransaction: validate repoIdArr as integers, build pathPlaceholders $1,$2,...,$n
        searchPgInTransaction->>BunSQL: SELECT id, repo_id, file_path FROM files WHERE repo_id IN (1,2,...) AND file_path IN ($1,$2,...)
        BunSQL-->>searchPgInTransaction: idRows[] → idMap
    end

    searchPgInTransaction-->>Caller: SearchResult[]

    Note over Caller: if includeSnippet:
    Caller->>withSnippets: withSnippets(repoRoot, config, results, query, currentRepoId)
    Note over withSnippets: validate resultRepoIds as integers, build pathPh $1,$2,...,$n
    withSnippets->>BunSQL: withRepoScope → SELECT repo_id, file_path, skeleton_entries FROM files WHERE repo_id IN (101,...) AND file_path IN ($1,$2,...)
    BunSQL-->>withSnippets: rows[] → entriesMap
    withSnippets-->>Caller: SearchResult[] with snippets
Loading

Reviews (1): Last reviewed commit: "fix(search): replace ANY($n) array param..." | Re-trigger Greptile

Comment thread src/search/query.ts Outdated
Adds a length check to prevent invalid `IN ()` SQL if resultRepoIds is
ever empty. Practically unreachable today but future-proofs the path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@smart-knowledge-systems

Copy link
Copy Markdown
Owner Author

P2 empty resultRepoIds guard addressed:

  • src/search/query.ts — added resultRepoIds.length > 0 to the outer guard so an empty set skips the query instead of producing invalid IN () SQL (6d89bb3)

@smart-knowledge-systems
smart-knowledge-systems merged commit 9358a19 into main Apr 15, 2026
1 check passed
smart-knowledge-systems added a commit that referenced this pull request May 8, 2026
Both branches converged on the same fix (replace ANY($n) array params with
IN ($1,$2,...) positional placeholders to work around Bun.SQL nested-array
misserialisation). Resolved src/search/query.ts and src/search/search-pg.ts
in favour of full positional parameterisation for both repo IDs and file
paths, and kept the empty-resultRepoIds guard from main (PR #25).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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