Skip to content

Windows: a file named nul in the repo makes every index_repository abort with aborted_previous_preserved (0.11.0) #2646

Closed

Description

@pereponkin

Environment

  • codebase-memory-mcp 0.11.0 (Windows 11, x64), daemon build 7edcd3807ebc…
  • Repository on NTFS, plain git checkout

What happens

A single empty file literally named nul in the repository root makes every index_repository run on that repository abort within ~3 s:

{"project":"<name>","status":"aborted_previous_preserved","hint":"Indexing aborted before publication; the previous index is intact and still serving. Causes: files changed while the run was in flight, or a discovery/manifest phase failed transiently. Retry; if it repeats, check the run log."}

It repeats on every retry (--mode full and --mode fast), so for an unindexed project no index is ever created. No run log survives (the worker log is unlinked on clean exit), so the only visible signal is the generic hint above, which points at "files changed" / "transient" causes rather than a deterministic one.

Such files are common on Windows: a shell command written as cmd > nul or 2>nul and run under Git Bash/MSYS creates a real file named nul. On Win32, opening <dir>\nul without the \\?\ prefix opens the NUL device, not that file.

The file was also listed in the repository's .gitignore (nul), and the run still aborted.

Reproduction

  1. Take any small git repository that indexes successfully.
  2. Create an empty file named nul in it (from Python: open(r"\\?\C:\path\to\repo\nul", "wb").close()).
  3. Optionally add nul to .gitignore.
  4. codebase-memory-mcp cli index_repository --repo-path C:\path\to\repo → aborted_previous_preserved.
  5. Delete the file (os.remove(r"\\?\C:\path\to\repo\nul")) → the same command returns indexed.

I verified this by bisection: a copy of the affected repository's git-visible files indexed fine; adding only an empty nul reproduced the abort; removing nul from the original repository fixed it.

Likely code path (tag v0.11.0, commit 8972ea6)

  • src/pipeline/pipeline_incremental.c:168 (semantic_manifest_hash_file): if (cbm_path_info_utf8(abs_path, &before) != 0 || !before.is_regular || before.is_symlink) { return CBM_NOT_FOUND; } — …\nul resolves to the device, so it is not a regular file.
  • src/pipeline/pipeline_incremental.c:512-515: any per-file failure ends the whole manifest: cbm_log_error("semantic_manifest.err", "path", files[i].path); rc = CBM_NOT_FOUND; break;
  • src/pipeline/pipeline.c:2740-2741: a failed baseline manifest becomes rc = CBM_PIPELINE_ABORT_PRESERVE_DB, reported as aborted_previous_preserved (src/mcp/mcp.c:11266).

I did not confirm from a log which of these lines fired, since the worker log is not kept; the bisection result is the hard evidence.

Expected

  • Discovery skips (or reports as not indexed) Windows reserved device names (nul, con, aux, prn, com1–com9, lpt1–lpt9, with or without extension), and honours .gitignore for them, so one junk file cannot block a whole repository.
  • If a file still cannot be hashed, the response names the path (the semantic_manifest.err path is already logged internally) instead of the generic "files changed / transient" hint.

Activity

  1. added
    bugSomething isn't working
    stability/performanceServer crashes, OOM, hangs, high CPU/memory
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    on Oct 19, 2026
  2. DeusData commented on Oct 19, 2026

    @DeusData
    Owner

    Thank you for isolating the reserved-name trigger by adding and removing just the empty nul file. That is useful evidence separate from the proposed code path. The deterministic abort and the generic diagnostic both need verification; there is no confirmed fix from this triage yet.

  3. meditecnic commented on Oct 22, 2026

    @meditecnic

    I was able to reproduce this locally on Windows with codebase-memory-mcp 0.12.1. This reproduction and comment were prepared with AI/Codex assistance.

    Environment

    • Windows x64 (OS build 22631), ANSI code page (ACP) 936
    • Python 3.11.9, Git 2.54.0.windows.1
    • Local binary SHA-256: 39f6a789cd858d7428561ac5afaefb9a47b018dcba0ad6fa41ae71a45e0ed656 (not yet cross-checked against an official upstream release asset)

    Setup

    A minimal synthetic Git repository, in a directory whose name includes Chinese characters and a space, containing:

    • A UTF-8 app.py with two functions
    • A .gitignore containing nul

    git check-ignore -v -- nul exits 0 and reports .gitignore:1:nul.

    A/B/A test

    I ran the following command at each step, using the same repository path, project name, and binary:

    codebase-memory-mcp cli index_repository --repo-path "<repo>" --name "<project>" --mode fast
    Step Change Index status Exit code
    A — Baseline No nul file indexed 0
    B Add an ignored, empty nul file aborted_previous_preserved 1
    A — Recovery Remove only the nul file indexed 0

    The real nul file in step B was created with Python using the Windows extended-length path prefix.

    Observations

    • In the baseline run, ASCII text search, Chinese text search, and symbol lookup all succeeded, confirming that the directory name itself did not block indexing on this setup.
    • No files were modified while indexing was in flight.
    • The failing run returned the generic aborted_previous_preserved hint and did not identify nul as the offending path.

    This is an independent reproduction of the symptom on my local 0.12.1 binary, rather than a source-level root-cause analysis or validation of the existing community fix. Happy to re-run this same A/B/A check against a candidate build if that would be helpful!

  4. DeusData commented on Oct 25, 2026

    @DeusData
    Owner

    Thank you for the independent 0.12.1 A/B/A check, including the ignored-file and non-ASCII-path controls. That adds useful evidence without claiming the proposed code path is verified. Sorry for the delay; the reserved-name abort and diagnostic need maintainer follow-up, and I’ll follow up soon.

  5. added a commit that references this issue on Nov 4, 2026
  6. DeusData commented on Nov 4, 2026

    @DeusData
    Owner

    Fixed on main by #2903 (merge commit 55206a8): a file named nul no longer aborts the index on Windows. Thanks again to @tanishqbaweja for the fix. The second suggestion here - naming the path that could not be read instead of the generic hint - is not part of this fix; we have noted it separately.

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 workingparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memorywindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions