Skip to content

Windows v0.8.1: stale graph + Permission denied on delete_project after orphan cbm process (reconfirm #277) #914

Description

@ibrahimqureshae

Summary

Just confirming that the symptoms from #277 ("New files not indexed on Windows") are still present in v0.8.1 on Windows 11. The same workaround from that issue (kill orphan codebase-memory-mcp.exe processes, delete the .db* files, reindex) is still the only thing that reliably gets the graph back in sync. New files added after the first index simply don't show up until a full reset.

Related: #520 ("watcher misses file creation") is also still open.

Environment

  • Version: 0.8.1
  • OS: Windows 11 (10.0.22631), x86_64
  • Install: official install.ps1 --ui, single static binary at %LOCALAPPDATA%\Programs\codebase-memory-mcp\
  • Agents: Claude Code (~/.claude/.mcp.json, ~/.claude.json) and opencode (~/.config/opencode/opencode.jsonc), both with --ui=true --port=9749
  • Config: auto_index=true, auto_watch=true to start with (I ended up turning auto_watch off, see below)
  • Cache: ~/.cache/codebase-memory-mcp/

What happens

I indexed a Rust project, then added some new files (a new module plus a few fixture files) on disk. When I tried to reindex:

  • index_repository comes back with incremental.noop reason=no_changes and the exact same node/edge counts as before (626/1298), even though the new files are right there on disk and git-tracked (git ls-files --error-unmatch finds them).
  • delete_project returns status:"delete_failed", error:"Permission denied" because the SQLite .db is still held open by a leftover cbm process.
  • search_graph for the new symbols (DomainSubdomains, run_scan, etc.) returns total: 0.
  • After killing all cbm processes and wiping the DB, a fresh index_repository reported pipeline.discover files=54 while the actual directory tree (excluding .git, .vscode, target, node_modules, dist, src-tauri/gen) had 97 files. The reindex did pick them up in the end (+206 nodes / +735 edges), so the parser is fine; it's the incremental path that keeps seeing "no changes" when there clearly are changes.

So on Windows this seems to have two faces:

  1. Stale hash table + orphan lock (per New files not indexed — WAL-checkpoint blocked on successfully-indexed project (Windows, v0.6.0) #277): the incremental reindex thinks nothing changed because it can't checkpoint new writes into the main .db.
  2. Discovery undercount: even from a clean cache, pipeline.discover files=N understates the on-disk file count. It still parses and indexes everything, but the log line is misleading when you're trying to diagnose a stale index.

Repro

# 1. Index a Rust repo via opencode (stdio MCP)
cd <your-rust-repo>
# (opencode spawns codebase-memory-mcp.exe as MCP server; let it index)
codebase-memory-mcp cli index_repository '{\"repo_path\":\"<absolute/path/to/repo>\"}'
# -> nodes: 626, edges: 1298   (baseline)

# 2. Add a new .rs module file plus a fixture file on disk
# (real edit in your editor; git-tracked, not gitignored)

# 3. Attempt explicit reindex
codebase-memory-mcp cli index_repository '{\"repo_path\":\"<absolute/path/to/repo>\"}'
# -> incremental.noop reason=no_changes
# -> nodes: 626, edges: 1298   (UNCHANGED; files on disk are newer)

# 4. Attempt delete
codebase-memory-mcp cli delete_project '{\"project\":\"<derived-project-name>\"}'
# -> status: delete_failed, error: Permission denied

# 5. Confirm orphan cbm processes exist
Get-Process -Name 'codebase-memory-mcp*' | Select Id, StartTime
# -> one process dating from before the new files were added (e.g. uptime 70 min)

# 6. Workaround (validates #277's root cause)
Get-Process -Name 'codebase-memory-mcp*' | Stop-Process -Force
Remove-Item \"$env:USERPROFILE\.cache\codebase-memory-mcp\<project-name>.db*\"
codebase-memory-mcp cli index_repository '{\"repo_path\":\"<absolute/path/to/repo>\"}'
# -> nodes: 832, edges: 2034   (+206 / +735)
# search_graph for the new symbol -> total: 1   CORRECT

Workaround script

I dropped this at %LOCALAPPDATA%\Programs\codebase-memory-mcp\cbm-reset.ps1 and run it after each Stage commit. Sharing in case other Windows users hit the same wall. It kills the orphans, deletes the stale DB, and reindexes:

[CmdletBinding()]
param(
  [Parameter(Position=0)] [string]$RepoPath = (Get-Location).Path,
  [switch]$ListOnly
)
$projectName = (($RepoPath -replace '[\\/]+','-') -replace '^-','' -replace '-$','') -replace ':',''
$cacheDir = Join-Path $env:USERPROFILE '.cache\codebase-memory-mcp'
$dbFiles  = Get-ChildItem $cacheDir -Filter \"$projectName.db*\" -ErrorAction SilentlyContinue

if ($ListOnly) {
  if (-not $dbFiles) { Write-Host \"No DB for $projectName\" } else {
    $dbFiles | ForEach-Object { Write-Host (\"  - {0}  ({1} KB, mod {2})\" -f $_.Name, [int]($_.Length/1KB), $_.LastWriteTime) }
  }
  $procs = Get-Process -Name 'codebase-memory-mcp*' -ErrorAction SilentlyContinue
  Write-Host (\"Live cbm processes: {0}\" -f @($procs).Count)
  $procs | Select Id, StartTime | Format-Table -AutoSize
  return
}

if ($dbFiles) {
  Write-Host \"Killing orphan codebase-memory-mcp.exe processes (releases SQLite locks)...\"
  Get-Process -Name 'codebase-memory-mcp*' -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
  Start-Sleep -Seconds 2
  $dbFiles | ForEach-Object { Remove-Item -LiteralPath $_.FullName -Force }
}
Write-Host \"Reindexing $RepoPath ...\"
& codebase-memory-mcp cli index_repository ('{\"repo_path\":\"' + ($RepoPath -replace '\\','/') + '\"}')
Write-Host \"Done. Restart Claude Code / opencode so they spawn a fresh MCP server.\"

What I had to give up

To stop the orphan accumulation I set auto_watch=false. The cost is losing the live-edit auto-sync; I now run cbm-reset.ps1 after each Stage commit and restart the agent. The daily workflow is fine, but the live-edit capability advertised in the README doesn't reliably work on Windows in v0.8.1.

Suggestions (reiterating #277, all still applicable)

  • On delete_project: run PRAGMA wal_checkpoint(TRUNCATE) before touching files on disk.
  • On stdio-close: trap stdio EOF / SIGTERM and run PRAGMA wal_checkpoint(TRUNCATE) plus a clean exit before the OS forces an orphan.
  • On startup: detect a stale .db-wal past a threshold (10 MB?) and either force-checkpoint or warn loudly.
  • Audit the Windows discovery path: pipeline.discover files=N doesn't match the on-disk file count even from a clean cache. That might be benign (N counts parsable units, not raw files), but the mismatch is confusing when you're trying to track down a stale index.
  • Document the orphan-process failure mode in the README troubleshooting section.

Happy to attach a cbm-diagnostics-<pid>.ndjson from a repro session if that'd be useful, just let me know which pid (orphan vs. new spawn) you'd want and I'll capture it with CBM_DIAGNOSTICS=1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions