Summary
All read commands (stats, query, map, cycles, triage, complexity, context, fn-impact, audit, deps, diff-impact, export, where, etc.) crash with codegraph: fatal error — disk I/O error when --db is passed a directory path (e.g. --db /path/to/repo).
The build command is not affected because it has its own path logic in pipeline.ts.
Root Cause
findDbPath at src/db/connection.ts:263:
export function findDbPath(customPath?: string): string {
if (customPath) return path.resolve(customPath); // ← returns directory as-is
...
}
When customPath is set (from --db), it does path.resolve(customPath) and returns the path verbatim — even when that path is a directory. All read commands then pass this directory path to new Database(dbPath, { readonly: true }), which tries to open a directory as a SQLite file and throws disk I/O error.
The build command avoids this because pipeline.ts appends .codegraph/graph.db:
ctx.dbPath = ctx.opts.dbPath
? path.resolve(ctx.opts.dbPath)
: path.join(ctx.rootDir, '.codegraph', 'graph.db');
But that logic is not applied to --db on read commands.
How to Reproduce
# Graph already built at /path/to/repo/.codegraph/graph.db
codegraph stats --db /path/to/repo # ← FAILS: disk I/O error
codegraph stats --db /path/to/repo/.codegraph/graph.db # ← works
codegraph query buildGraph --db /path/to/repo # ← FAILS
codegraph map --db /path/to/repo # ← FAILS
Expected Behavior
--db /path/to/repo should auto-resolve to /path/to/repo/.codegraph/graph.db for all commands, consistent with how build handles it.
Fix
In findDbPath, detect when customPath resolves to a directory and append .codegraph/graph.db:
export function findDbPath(customPath?: string): string {
if (customPath) {
const resolved = path.resolve(customPath);
// If customPath is a directory, append the conventional DB location
if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
return path.join(resolved, '.codegraph', 'graph.db');
}
return resolved;
}
...
}
Impact
This is a critical UX regression — the canonical usage documented in the README (--db <repo-root>) silently fails for every read command. Users hit the error immediately after build and have no clear hint that they need --db <repo>/.codegraph/graph.db instead.
Verified On
- Version: 3.15.0
- Platform: darwin-arm64, macOS 26.2, Node v24.10.0
- Native engine v3.15.0
Workaround
Pass the full path: codegraph stats --db /path/to/repo/.codegraph/graph.db
Summary
All read commands (
stats,query,map,cycles,triage,complexity,context,fn-impact,audit,deps,diff-impact,export,where, etc.) crash withcodegraph: fatal error — disk I/O errorwhen--dbis passed a directory path (e.g.--db /path/to/repo).The
buildcommand is not affected because it has its own path logic inpipeline.ts.Root Cause
findDbPathatsrc/db/connection.ts:263:When
customPathis set (from--db), it doespath.resolve(customPath)and returns the path verbatim — even when that path is a directory. All read commands then pass this directory path tonew Database(dbPath, { readonly: true }), which tries to open a directory as a SQLite file and throwsdisk I/O error.The
buildcommand avoids this becausepipeline.tsappends.codegraph/graph.db:But that logic is not applied to
--dbon read commands.How to Reproduce
Expected Behavior
--db /path/to/reposhould auto-resolve to/path/to/repo/.codegraph/graph.dbfor all commands, consistent with howbuildhandles it.Fix
In
findDbPath, detect whencustomPathresolves to a directory and append.codegraph/graph.db:Impact
This is a critical UX regression — the canonical usage documented in the README (
--db <repo-root>) silently fails for every read command. Users hit the error immediately after build and have no clear hint that they need--db <repo>/.codegraph/graph.dbinstead.Verified On
Workaround
Pass the full path:
codegraph stats --db /path/to/repo/.codegraph/graph.db