fix(agent): on Windows the file tools take a device name such as nul for a workspace file
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 45/100
Research direction
Start in resolve_path in raven/agent/tools/filesystem.py, where the workspace join and Path.resolve() check happen, then trace how WriteFileTool.execute uses it. Reproduce with the script in the issue on a Windows machine, or add a unit test that stubs the Windows path behaviour. Done when resolve_path raises PermissionError for reserved device names such as nul, con and nul.md, and the file-tool tests cover that refusal.
Written by the indexing model from the issue text.
Description
Summary
resolve_path (raven/agent/tools/filesystem.py) is the path policy behind read_file, write_file, edit_file, list_dir, grep/find, deliver_files, the RPC file viewer and turn attachments. On Windows it accepts a reserved DOS device name as an ordinary file inside the workspace. write_file with path="nul" should therefore send the content to the NUL device and still answer Successfully wrote ... bytes to <workspace>\nul, with a diff and a file_change for a file that was never created.
Why the fence lets it through: resolve_path joins a relative path onto the workspace and then calls Path.resolve(), which on Windows is ntpath.realpath. In CPython 3.12 that function special-cases a device only when the whole path is exactly nul (if normcase(path) == normcase(devnull): return '\\\\.\\NUL'), so <workspace>\nul falls through to _getfinalpathname, whose non-strict fallback hands the joined path back unchanged; relative_to(<workspace>) then accepts it.
Which names reach a device depends on the Windows version. nul maps to the NUL device in every directory on every version, Windows 11 included (CPython issue 95486). On Windows 10 and earlier so do CON, PRN, AUX, COM0-COM9 and LPT0-LPT9, with or without an extension (nul.md is NUL), per Microsoft's "Naming Files, Paths, and Namespaces"; Windows 11 treats most of them as ordinary names once they carry an extension.
This is not a write outside the workspace: the data goes to a device rather than to another path. The harm is a tool result that reports a save that did not happen (and, for CON on Windows 10, file content written to the console).
Found while reviewing #890, which adds a control-character refusal to resolve_path and leaves this case as it was. resolve_path is unchanged on main at c3d28213036c.
Steps to reproduce
Not run on Windows yet: I have no Windows machine, and CI runs no Windows job over the file-tool tests. On Windows, with Raven installed:
import asyncio, pathlib, tempfile
from raven.agent.tools.filesystem import WriteFileTool
ws = pathlib.Path(tempfile.mkdtemp())
tool = WriteFileTool(workspace=ws, allowed_dirs=(ws,))
for name in ("nul", "nul.md", "con.md", "report.md"):
r = asyncio.run(tool.execute(path=name, content="hello\n"))
print(name, "->", getattr(r, "model_text", r))
print("on disk:", sorted(p.name for p in ws.iterdir()))
On Linux the same script writes four regular files, which is the expected shape.
Expected behavior
resolve_path refuses a reserved device name with a PermissionError, as it does for a path outside the allowed directories, so every caller reports an error rather than a save. Python 3.13's os.path.isreserved (absent from 3.12, which Raven supports) defines the set: device names with or without an extension in any component, CONIN$/CONOUT$, and also names ending in a dot or a space and name:stream paths, which have the same reported-path-is-not-the-file shape on Windows.
Actual behavior
Expected from the code, not yet observed: nul -> Successfully wrote ... bytes to <workspace>\nul with no nul on disk on any Windows version; on Windows 10 and earlier nul.md and con.md behave the same way.
Environment
OS: Windows (derived from CPython 3.12.13 Lib/ntpath.py and the Win32 naming rules; not reproduced)
Python: 3.12
Raven: main at c3d28213036c
Logs or screenshots
None yet; the script above prints them.
- Dominant language
- Python
- Stars
- 4.1k
- Forks
- 94
- Avg merge
- 13h 42m
- Merged PRs (30d)
- 402
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from EverMind-AI/Raven
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
EverMind-AI/Raven#1000 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
EverMind-AI/Raven#998 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
EverMind-AI/Raven#997 ·
Maintainers usually reply within 1 day
-
fix: two error hints tell users to install raven by name, which is Sentry's client on PyPIPossibly taken @TheIrvin claimed this 15 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
EverMind-AI/Raven#845 · 2 comments ·
Maintainers usually reply within 1 day
-
security: tool output scrubbing misses raven's own oauth token filesPossibly taken @akushonkamen claimed this 7 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
EverMind-AI/Raven#842 · 2 comments ·
Maintainers usually reply within 1 day
All issues in EverMind-AI/Raven
Similar issues
-
comp/cli P3 type/security
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
NousResearch/hermes-agent#141420 · 1 comment ·
Maintainers usually reply within 1 day
-
vendor-pitch
Difficulty 2/5 1-3 hours Newbie friendliness 87/100
Maintainers usually reply within 1 day
-
bug llm p2
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
New tool: ZIPZAX Python Notebook StudioPossibly taken @github-actions claimed this today. Opensubmission triage
Difficulty 1/5 Under an hour Newbie friendliness 68/100
kausalflow/tools#226 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100