Skip to content

[v0.9.0][Windows] persistence=true crashes the indexing worker for repositories under CJK paths #1171

Closed

Description

@Akii-kawaii

Version

codebase-memory-mcp 0.9.0

Platform

Windows (x64)

Install channel

GitHub release archive / install.sh / install.ps1

Binary variant

standard

What happened, and what did you expect?

Summary

On Windows 11 x64 with the official v0.9.0 Windows amd64 standard binary, a clean full index of the public DeusData/codebase-memory-mcp repository succeeds from a CJK path when persistence=false, but the supervised worker exits nonzero when the same repository is indexed from the same CJK path with persistence=true.

An ASCII NTFS junction pointing to that exact CJK directory succeeds with persistence=true and writes .codebase-memory/graph.db.zst. The three-way result reproduced twice from clean project names, isolating the failure to persistence export for the non-ASCII path.

The failed run leaves a readable SQLite database (PRAGMA integrity_check = ok) and index_status reports ready, but the explicit index call returns exit_nonzero and no artifact is created.

Expected behavior

  • A clean persistent index should work for a repository under a CJK path and write .codebase-memory/graph.db.zst.
  • The canonical CJK path and an ASCII junction to the same directory should behave identically.
  • If export fails, the response and worker log should expose the actual Windows path/file error.
  • A failed explicit index should not be reported as ready without making the failed persistence state clear.

Query-phase CJK path behavior is tracked separately by #903 and is out of scope here.

Related: #400, #434, #903, and PR #891.

Reproduction

Environment

  • OS: Windows 11 x64, build 10.0.26200
  • PowerShell: 5.1.26100.8875; active code page: 936
  • Binary: official v0.9.0 Windows amd64 standard release
  • SHA-256: 9A205FA5AE759FBC866BFE1554F0C05A303BE9AE6E0A00F94D875DC0C25E0680
  • Public repository: https://github.com/DeusData/codebase-memory-mcp.git
  • Tag / commit: v0.9.0 / b637e3330c96cfe452da623db068c241aaa3ec01

Setup

$cbm = "$env:USERPROFILE\.local\bin\codebase-memory-mcp.exe"
$cjkRepo = Join-Path $env:LOCALAPPDATA 'Temp\cbm-持久化复现'
$asciiRepo = Join-Path $env:LOCALAPPDATA 'Temp\cbm-cjk-repro'

git clone --depth 1 --branch v0.9.0 --single-branch `
  https://github.com/DeusData/codebase-memory-mcp.git $cjkRepo
git -C $cjkRepo rev-parse HEAD
# b637e3330c96cfe452da623db068c241aaa3ec01

New-Item -ItemType Junction -Path $asciiRepo -Target $cjkRepo

Every scenario started with delete_project, so every index was a clean full run rather than an incremental run.

1. CJK path, persistence=false

$project = 'cbm-v090-public-cjk-pfalse-r2'
& $cbm cli delete_project --project $project
& $cbm cli index_repository --repo-path $cjkRepo --mode moderate --name $project --persistence false

Result: status=indexed, nodes=13007, edges=73886, skipped_count=0, artifact_present=false; SQLite integrity_check=ok; File nodes: 556.

2. Same CJK path, persistence=true

$project = 'cbm-v090-public-cjk-ptrue-r2'
& $cbm cli delete_project --project $project
& $cbm cli index_repository --repo-path $cjkRepo --mode moderate --name $project --persistence true
{"status":"error","outcome":"exit_nonzero","hint":"Indexing worker crashed on a file. The crash was contained (the server survived). Re-run to retry; a future release isolates the culprit file.","repo_path":"%LOCALAPPDATA%\\Temp\\cbm-持久化复现"}

Result: worker exit 1; empty worker log; database integrity_check=ok; nodes=13007, edges=73864, File nodes 556; skipped_count not reported; artifact absent. index_status immediately returned ready.

3. ASCII junction to the same CJK directory, persistence=true

$project = 'cbm-v090-public-ascii-ptrue-r2'
& $cbm cli delete_project --project $project
& $cbm cli index_repository --repo-path $asciiRepo --mode moderate --name $project --persistence true

Result: status=indexed, nodes=13007, edges=73754, skipped_count=0, artifact_present=true; SQLite integrity_check=ok; File nodes 556; artifact 9,162,274 bytes, compression level 9, commit b637e3330c96cfe452da623db068c241aaa3ec01.

Repeated control matrix

Scenario Run 1 Run 2
CJK, persistence=false indexed; 13,007 nodes / 74,585 edges; skipped 0; no artifact; SQLite ok indexed; 13,007 / 73,886; skipped 0; no artifact; SQLite ok
CJK, persistence=true worker exit 1; 13,007 / 73,895; skipped not reported; no artifact; SQLite ok worker exit 1; 13,007 / 73,864; skipped not reported; no artifact; SQLite ok
ASCII junction, persistence=true indexed; 13,007 / 73,941; skipped 0; artifact 9,156,778 bytes; SQLite ok indexed; 13,007 / 73,754; skipped 0; artifact 9,162,274 bytes; SQLite ok

The edge-count variation occurs across all three scenarios and is not used as the pass/fail criterion. The invariant signals are the worker exit status and artifact creation.

Workaround

Create an ASCII NTFS junction to the CJK repository directory, delete the old project, and run the full persistent index through the junction.

Logs

level=info msg=index.supervisor.reap outcome=exit_nonzero exit_code=1 signal=0
level=warn msg=index.supervisor.worker_failed outcome=exit_nonzero exit_code=1 log=%USERPROFILE%/.cache/codebase-memory-mcp/logs/.worker-42772.log
{"status":"error","outcome":"exit_nonzero","hint":"Indexing worker crashed on a file. The crash was contained (the server survived). Re-run to retry; a future release isolates the culprit file.","repo_path":"%LOCALAPPDATA%\\Temp\\cbm-持久化复现"}

Referenced worker log:
%USERPROFILE%\.cache\codebase-memory-mcp\logs\.worker-42772.log
Length: 0 bytes

Failed database:
integrity=ok
nodes=13007
edges=73864
files=556
skipped_count=not reported in error JSON
artifact_exists=false

ASCII junction control:
level=info msg=index.supervisor.reap outcome=clean exit_code=0 signal=0
{"project":"cbm-v090-public-ascii-ptrue-r2","skipped_count":0,"nodes":13007,"edges":73754,"artifact_present":true,"status":"indexed"}

Diagnostics trajectory (memory / performance / leak issues)

Not applicable. This is a deterministic path- and persistence-dependent worker exit; no memory growth, hang, or leak was observed.

Project scale (if relevant)

Public repository at b637e33:1,818 tracked files; 556 indexed File nodes; 13,007 graph nodes; 73,754–74,585 graph edges across clean runs; 8 excluded directories; 0 skipped files on successful runs.

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Activity

  1. changed the title [-][v0.9.0][Windows] persistence export crashes the indexing worker for repositories under CJK paths[/-] [+][v0.9.0][Windows] persistence=true crashes the indexing worker for repositories under CJK paths[/+] on Jul 19, 2026
  2. added
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Jul 19, 2026
  3. added this to the 0.9.1-rc milestone on Jul 19, 2026
  4. DeusData commented on Jul 19, 2026

    @DeusData
    Owner

    Thanks for the controlled CJK-path versus ASCII-junction matrix. This is now high priority in 0.9.1-rc under the Windows platform epic #394. The evidence isolates the persistent-artifact export path; the empty worker log and ready status after a failed persistence request are part of the bug, not separate cosmetic concerns.

  5. Akii-kawaii commented on Jul 20, 2026

    @Akii-kawaii
    Author
  6. DeusData commented on Oct 1, 2026

    @DeusData
    Owner

    Thank you again, @Akii-kawaii, for the CJK-path versus ASCII-junction matrix. Isolating the failure to the persistence export made the cause easy to find, and I'm sorry this took so long.

    The artifact code still used ANSI-code-page file APIs on Windows, so any non-ASCII path failed:

    • the temp-file writer (fopen) and the rename into place (MoveFileExA);
    • the import publish (rename) and the existence check (stat);
    • and the .gitattributes file created next to graph.db.zst (open).

    So with persistence=true under a CJK path, the export could not create its temp file, and no graph.db.zst was written. The ASCII junction worked because the same bytes then stayed inside the code page.

    The fix in #2461 routes all of these through the project's UTF-8 path layer, which uses the wide-character Windows APIs (_wfopen, MoveFileExW, _wstat64). We verified it on a real Windows machine whose ANSI code page cannot represent the path (cp1252):

    • before: the export failed with open_temp errno=2, 3 runs out of 3;
    • after: export plus two imports into a CJK cache dir succeed, and .gitattributes gets its merge=ours line, 3 runs out of 3.

    If you still have your matrix set up, a retest with the next release (or a build of #2461) would be very welcome.

  7. added a commit that references this issue on Oct 7, 2026
  8. DeusData commented on Oct 7, 2026

    @DeusData
    Owner

    The fix from #2461 has now landed on main in d19cab8 and will ship in the next release. @Akii-kawaii, thank you again for your patience and for the offer to retest: once the release is out, a run of your CJK-path versus ASCII-junction matrix with persistence=true would be the best confirmation we could get. If anything still fails, just comment here and we will reopen it.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memoryux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions