Skip to content

fix: hydrate worker DB in server mode + fix LadybugDB getAll API mismatch#404

Merged
abhigyanpatwari merged 1 commit into
abhigyanpatwari:mainfrom
fabianhug:fix/server-mode-worker-hydration
Mar 21, 2026
Merged

fix: hydrate worker DB in server mode + fix LadybugDB getAll API mismatch#404
abhigyanpatwari merged 1 commit into
abhigyanpatwari:mainfrom
fabianhug:fix/server-mode-worker-hydration

Conversation

@fabianhug

Copy link
Copy Markdown
Contributor

Summary

Fixes #398 — server/bridge mode leaves the web UI with 0 nodes, broken Query/Processes tabs, and Database not ready errors.

Root cause: When connecting via gitnexus serve, the main thread builds the React-side graph but never hydrates the worker's LadybugDB or BM25 indexes. All features that depend on the worker-side DB (Query, Processes, Nexus AI, embeddings) fail.

Secondary bug: result.getAll() does not exist in some @ladybugdb/wasm-core versions, causing TypeError: result.getAll is not a function on every Cypher query.

Changes

1. Worker hydration for server mode (ingestion.worker.ts)

  • New hydrateFromServerData() method that takes server-loaded nodes, relationships, and file contents and:
    • Builds a KnowledgeGraph in the worker
    • Stores file contents for grep/read tools
    • Builds BM25 keyword index
    • Loads the graph into LadybugDB for Cypher queries
    • Sets currentGraphResult for the agent context builder

2. Call hydration after server connect (App.tsx, useAppState.tsx)

  • handleServerConnect and switchRepo now call hydrateWorkerFromServer() after setting the React graph
  • Embeddings and agent initialization are deferred until hydration completes
  • progress is cleared after successful server connection (fixes status bar stuck on "Processing...")

3. LadybugDB getAll API compatibility (lbug-adapter.ts)

  • All result.getAll() calls now fall back to getAllObjects()getAllRows()[]
  • Fixes compatibility across different @ladybugdb/wasm-core versions

Repro (before fix)

  1. gitnexus analyze a repository
  2. gitnexus serve
  3. Open gitnexus-web, connect to server
  4. Graph loads in the canvas but Query/Processes/Nexus AI fail with "Database not ready"
  5. Status bar stuck on "Processing..."
  6. Embeddings fail with "Database not ready. Please load a repository first."

After fix

  • Server-loaded graph is fully functional: Query, Processes, embeddings, and Nexus AI all work
  • Status bar correctly shows "Ready" after connection
  • No more getAll is not a function errors

…atch (abhigyanpatwari#398)

Fix server/bridge mode leaving the web UI with 0 nodes and broken
Query/Processes/embeddings by hydrating the worker-side LadybugDB
and BM25 indexes after loading graph data from the backend.

Also fix LadybugDB QueryResult API mismatch where result.getAll()
does not exist in some @ladybugdb/wasm-core versions — falls back
to getAllObjects() or getAllRows().
@vercel

vercel Bot commented Mar 21, 2026

Copy link
Copy Markdown

@fabianhug is attempting to deploy a commit to the NexusCore Team on Vercel.

A member of the Team first needs to authorize it.

@fabianhug

Copy link
Copy Markdown
Contributor Author

lmk if anything needs to be changed for it to be approved, it's breaking and you can't connect your local repos, so a quick fix would be great

@abhigyanpatwari

@vercel

vercel Bot commented Mar 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gitnexus Ready Ready Preview, Comment Mar 21, 2026 0:26am

Request Review

@abhigyanpatwari

Copy link
Copy Markdown
Owner

@claude review this

@github-actions

github-actions Bot commented Mar 21, 2026

Copy link
Copy Markdown
Contributor

Claude finished @abhigyanpatwari's task in 2m 1s —— View job


Code Review

  • Gather context
  • Read changed files
  • Analyze implementation
  • Post review feedback

Summary: The fix correctly identifies and addresses a real bug — the worker-side DB was never hydrated in server mode. The implementation is generally clean with good error handling. A few issues worth addressing:


ingestion.worker.tshydrateFromServerData

Good:

  • Correctly mirrors the initialization sequence from runPipeline (graph → fileContents → BM25 → currentGraphResult → LadybugDB)
  • LadybugDB failure is properly non-fatal with graceful degradation
  • DEV-mode logging is well-placed

Issue — serialization overhead: Comlink structured-clones nodes, relationships, and fileContents on every call. For large repos, this is a full deep copy of data that the worker originally produced (in runPipeline) or that the main thread downloaded. Since the architecture requires main thread → worker transfer here, this is unavoidable, but worth documenting or noting a future optimization.

Issue — currentGraphResult type safety (line 237):

currentGraphResult = { graph, fileContents: storedFileContents };

If PipelineResult has additional required fields beyond graph and fileContents, this will fail at runtime even if TypeScript doesn't catch it. Worth explicitly checking the PipelineResult type definition.


lbug-adapter.tsgetAll fallback chain

Good: The fallback pattern result.getAll?.() ?? result.getAllObjects?.() ?? result.getAllRows?.() ?? [] is a pragmatic cross-version compatibility fix.

Minor — repeated pattern (8+ occurrences): This chain is now duplicated throughout the file. Extracting it to a one-line helper would reduce repetition and make future version changes easier:

const getAllRows = (result: any): any[] =>
  result.getAll?.() ?? result.getAllObjects?.() ?? result.getAllRows?.() ?? [];

Fix this →


App.tsxhandleServerConnect (lines 136–185)

Good:

  • Agent init and embeddings are correctly deferred until after hydration
  • Fallback .catch() still calls initializeAgent so the agent works even if LadybugDB fails

Issue — UI shows "Ready" before DB is hydrated (lines 159–163):

setViewMode('exploring');
setProgress(null);  // Status bar shows "Ready"

// But hydration happens async AFTER this
hydrateWorkerFromServer(...).then(() => { ... });

There's a window where the user is in the exploring view and Query/Processes tabs will return "Database not ready". Consider keeping a progress state during hydration (e.g., "Indexing...") before clearing it, or checking isReady() in the Query tab before executing.
Fix this →


useAppState.tsxhydrateWorkerFromServer

Issue — weak typing (line 486–490):

const hydrateWorkerFromServer = useCallback(async (
  nodes: any[],           // should be GraphNode[]
  relationships: any[],   // should be GraphRelationship[]
  fileContents: Record<string, string>

Both GraphNode and GraphRelationship are already imported in this file. Using any[] loses type safety for callers.
Fix this →


Overall

The core fix is correct and well-structured. The three issues above — currentGraphResult type check, race condition between setProgress(null) and hydration, and weak typing — are worth addressing before merge. The getAll helper extraction is a nice-to-have cleanup. No blocking security or correctness issues beyond the race condition.

@github-actions

Copy link
Copy Markdown
Contributor

CI Report

All checks passed4d27d49

Pipeline

Stage Status Ubuntu Windows macOS
Typecheck success
Tests success

Tests

Metric Value
Total 3459
Passed 3439
Skipped 20
Files 998
Duration 1m 51s

✅ All 3439 tests passed across 998 files

20 test(s) skipped
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature
  • Python match/case as-pattern type binding > resolves u.save() to User#save via match/case as-pattern binding
  • Python match/case as-pattern type binding > does NOT resolve u.save() to Repo#save (negative disambiguation)
  • Swift constructor-inferred type resolution > detects User and Repo classes, both with save methods
  • Swift constructor-inferred type resolution > resolves user.save() to Models/User.swift via constructor-inferred type
  • Swift constructor-inferred type resolution > resolves repo.save() to Models/Repo.swift via constructor-inferred type
  • Swift constructor-inferred type resolution > emits exactly 2 save() CALLS edges (one per receiver type)
  • Swift self resolution > detects User and Repo classes, each with a save function
  • Swift self resolution > resolves self.save() inside User.process to User.save, not Repo.save
  • Swift parent resolution > detects BaseModel and User classes plus Serializable protocol
  • Swift parent resolution > emits EXTENDS edge: User → BaseModel
  • Swift parent resolution > emits IMPLEMENTS edge: User → Serializable (protocol conformance)
  • Swift cross-file User.init() inference > resolves user.save() via User.init(name:) inference
  • Swift cross-file User.init() inference > resolves user.greet() via User.init(name:) inference
  • Swift return type inference > detects User class and getUser function
  • Swift return type inference > detects save function on User (Swift class methods are Function nodes)
  • Swift return type inference > resolves user.save() to User#save via return type of getUser() -> User
  • Swift return-type inference via function return type > resolves user.save() to User#save via return type of getUser()
  • Swift return-type inference via function return type > user.save() does NOT resolve to Repo#save
  • Swift return-type inference via function return type > resolves repo.save() to Repo#save via return type of getRepo()

Coverage

Metric Coverage Covered Base (main) Delta
Statements 68.14% 8703/12772 68.14%
Branches 59.43% 5946/10004 59.44%
Functions 70.27% 754/1073 70.27%
Lines 70.46% 7779/11039 70.46%

📋 Full run · Coverage from Ubuntu · Generated by CI

@abhigyanpatwari

Copy link
Copy Markdown
Owner

Thanks for reporting and quick fix. Merging it

@abhigyanpatwari abhigyanpatwari merged commit 11575cf into abhigyanpatwari:main Mar 21, 2026
8 checks passed
@fabianhug

Copy link
Copy Markdown
Contributor Author

always, keep up the good work @abhigyanpatwari

icodebuster pushed a commit to icodebuster/GitNexus that referenced this pull request Mar 22, 2026
* main: (67 commits)
  fix(server): allow private/LAN network origins in CORS (abhigyanpatwari#390)
  fix(ingestion): calculate confidence per resolution tier for heritage/MRO edges (abhigyanpatwari#412)
  fix(lbug): retry on DB lock with session-safe cleanup (abhigyanpatwari#325)
  fix(analyze): address review — rename --no-git to --skip-git, fix stale cache
  fix(analyze): address Copilot review — ESM import, CLI option, .gitignore guard
  docs(schema): add Community and Process node properties to cypher tool description (abhigyanpatwari#411)
  fix(analyze): allow indexing folders without a .git directory (abhigyanpatwari#384)
  token trunking
  updated mahalanobis threshold to be multi-dim aware
  fix: clarify that ORT CUDA binaries are linux/x64 only
  updating workflow verbage
  fixed prop cutoff issue for pr/issue filtering
  fix: update symbol and relationship counts in documentation
  fix: address PR abhigyanpatwari#409 review findings (P0-P3) and simplify import resolution API
  refactor: unify language dispatch with compile-time exhaustive tables
  feat: implement cross-file binding propagation for multiple languages
  fix: hydrate worker DB in server mode + fix LadybugDB getAll API mismatch (abhigyanpatwari#398) (abhigyanpatwari#404)
  docs: add gitnexus-stable-ops to community integrations
  fix: register Section in NODE_TABLES and NODE_SCHEMA_QUERIES (abhigyanpatwari#401)
  feat: add markdown file indexing (headings + cross-links) (abhigyanpatwari#399)
  ...
motolese pushed a commit to motolese/datamoto-gitnexus that referenced this pull request Apr 23, 2026
…atch (abhigyanpatwari#398) (abhigyanpatwari#404)

Fix server/bridge mode leaving the web UI with 0 nodes and broken
Query/Processes/embeddings by hydrating the worker-side LadybugDB
and BM25 indexes after loading graph data from the backend.

Also fix LadybugDB QueryResult API mismatch where result.getAll()
does not exist in some @ladybugdb/wasm-core versions — falls back
to getAllObjects() or getAllRows().
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.

gitnexus-web: server mode can stay stuck on Processing and leave Query/Processes not ready after repo switch

2 participants