Skip to content

[BUG] Watch service crashes every cycle when a project lives on a Windows mapped network drive (relative_to mixes UNC and drive-letter paths) #1047

Description

@nlitesoft

Bug Description

On Windows, if a project's configured path is on a mapped network drive (e.g. S:\ mapped to \server\share), the watch service throws a ValueError on every batch of file changes and
the entire watch cycle aborts - live sync never processes any changes for any project. Startup/initial sync works fine; only the live watch loop is affected.

Steps To Reproduce

  1. Install Basic Memory 0.22.1 on Windows (uv tool install basic-memory)
  2. Map a network share to a drive letter, e.g. net use S: \server\share
  3. Add a project whose path uses the drive letter, e.g. basic-memory project add notes S:\Notes
  4. Start the MCP server (basic-memory mcp) and modify any file inside the project
  5. See Watch service error during cycle with a ValueError traceback in the log, repeating on every change

Expected Behavior

File changes under the mapped-drive project are synced to the knowledge base, as they are for local-drive projects.

Actual Behavior

Every change batch raises, aborting the whole watch cycle (all projects):

ERROR | basic_memory.sync.watch_service:run:255 - Watch service error during cycle
...
File ".../basic_memory/sync/watch_service.py", line 375, in handle_changes
relative_path = Path(path).relative_to(directory).as_posix()
│ │ └ WindowsPath('//server/share/Notes')
│ └ 'S:/Notes\subdir\file.md.tmp.4648.fc05f140aea6'
File ".../pathlib/_local.py", line 385, in relative_to
raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}")
ValueError: 'S:\Notes\subdir\file.md.tmp...' is not in the subpath of '\\server\share\Notes'

Because the error fires before the .tmp filter (line 378), editor temp files trigger it constantly; the log grows by ~900 KB of repeated tracebacks per session.

Environment

  • OS: Windows 11 Pro (10.0.26200)
  • Python version: 3.13.11
  • Basic Memory version: 0.22.1
  • Installation method: uv tool
  • Claude Desktop version: n/a (Claude Code MCP, stdio transport)

Additional Context

Project configured with a drive-letter path in config.json:

"notes": { "path": "S:\Notes", "mode": "local" }

Root cause in basic_memory/sync/watch_service.py, handle_changes():

directory = Path(project.path).resolve() # line 363
...
relative_path = Path(path).relative_to(directory).as_posix() # line 375

On Windows, Path.resolve() expands a mapped drive letter to its UNC form, so directory becomes \server\share\Notes. But path comes from watchfiles in the original drive-letter form
and is never resolved, so relative_to() always fails. The exception propagates through asyncio.gather in _watch_projects_cycle (line 175) and kills the cycle for all projects.

Possible Solution

Resolve the change path the same way the project directory is resolved:

relative_path = Path(path).resolve().relative_to(directory).as_posix()

(or normalize both sides with os.path.relpath). Note is_project_path() at line 339 already resolves both sides; handle_changes() only resolves one.

Activity

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 working

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions