Skip to content

Windows: index always fails with generic 'Pipeline failed' — protected-DACL cache dir breaks MoveFileExW(REPLACE_EXISTING) on this host #1620

Description

@roosteer

Summary

On this Windows host, every index_repository run fails with the generic hint:

{"project":"...","status":"error","hint":"Pipeline failed. Check repo_path exists and contains source files. Try mode='fast' for a quicker diagnostic run."}

The pipeline itself runs all passes successfully (including gbuf.dump), the supervised worker exits 0 (index.supervisor.reap outcome=clean), no error-level log line is emitted anywhere, and no .db is ever published. A 1-file Go repo fails identically, so it is host-specific, not repo-specific. ui.config.write_fail ... reason=atomic_publish appears repeatedly in the daemon log as well.

Root cause (verified end-to-end)

The failure is an interaction between the Windows cache-DACL hardening and MoveFileExW on this host:

  1. Since v0.9.1-rc.1, every CBM process start re-applies a protected, owner-only DACL to the cache directory (win_runtime_directory_secure in src/daemon/ipc.c, cbm_windows_stamp_dir_owner in src/foundation/compat_fs.c; re-applied unconditionally on each process start, not only at creation).
  2. On this machine, MoveFileExW(src, dst, MOVEFILE_REPLACE_EXISTING) returns ERROR_ACCESS_DENIED (5) inside any directory whose DACL is protected (inheritance disabled), while plain rename, create and delete all work. Reproduced independently of CBM:
    • cmd /c "move /y r2.txt r1.txt"Access is denied in the protected dir, works in %TEMP% and in sibling dirs with inherited ACLs.
    • Synthetic dirs: icacls /inheritance:r + single owner ACE → fails; icacls /inheritance:e → works.
  3. CBM publishes the index via rename-replace (publish_writer_output in src/sqlite_writer.ccbm_rename_replaceMoveFileExW; also finalize_staged_generation). The failure is silent (CBM_PIPELINE_PERSIST_FAILED with no log), which produces the misleading generic hint.
  4. Proof: keeping the cache dir ACL in the healthy (inherited) state during a run (background loop re-applying icacls /inheritance:e while the pipeline executes) makes the exact same index succeed: status:"indexed", .db published.

So on this host the hardening itself makes the cache dir unusable for the rename-replace the pipeline depends on. No config switch exists to disable it (a non-conforming DACL is re-hardened; denying WRITE_DAC fails the daemon closed; UNC paths are refused; CBM_CACHE_DIR elsewhere gets hardened the same way).

Environment

Version 0.10.4
OS Windows (domain-joined, UAC enabled, user in Administrators)
Cache dir C:\Users\...\.cache\codebase-memory-mcp (default)

Related

Suggested fixes

  1. Fallback publish path when rename-replace fails (e.g. copy+delete, or write the final name directly) instead of silent PERSIST_FAILED.
  2. Make the DACL hardening opt-out (env var) for hosts where it conflicts with local security policy.
  3. At minimum: log the real OS error (which operation failed with which code) instead of the generic "Pipeline failed" hint — the current silence cost a full day of investigation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions