Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

fix(agent): on Windows the file tools take a device name such as nul for a workspace file

Open
#895 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@akushonkamen is already working on this.

Since Oct 11, 2026.

  • #918 by @akushonkamen — open

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
backend, security

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

bug
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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from EverMind-AI/Raven

All issues in EverMind-AI/Raven

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.