agentscope-ai/agentscope · error · HTTPException
Requested path is a directory, not a file.
Error message
Requested path is a directory, not a file.
What it means
Raised by read_workspace_file when the requested workspace path exists but is a directory rather than a regular file. The router checks the entry's is_dir flag after confirming existence and rejects directory paths because a file download/read endpoint cannot stream a directory. It is an HTTP 400 because the request is syntactically valid but semantically wrong for this endpoint.
Source
Thrown at src/agentscope/app/_router/_workspace.py:590
)
workspace = await workspace_service.resolve(
user_id,
agent_id,
session_id,
)
backend = workspace.get_backend()
target = backend.abspath(path, cwd=workspace.workdir)
basename = backend.basename(target) or "download"
entry = await backend.stat(target)
if entry is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="File not found.",
)
if entry.is_dir:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Requested path is a directory, not a file.",
)
headers: dict[str, str] = {}
# Lets the browser show real download progress instead of a
# spinner of unknown length; omitted when the backend cannot stat.
if entry.size_bytes is not None:
headers["Content-Length"] = str(entry.size_bytes)
if download:
headers[
"Content-Disposition"
] = f"attachment; filename*=UTF-8''{quote(basename)}"
return StreamingResponse(
backend.read_stream(target),
media_type=(
mimetypes.guess_type(basename)[0] or "application/octet-stream"View on GitHub (pinned to e90f1c7592)
Solutions
- Verify the path points to a file (e.g. via the workspace listing endpoint) before calling read_workspace_file
- If you meant to fetch a file inside the folder, append the filename: 'docs/' -> 'docs/README.md'
- If you need directory contents, call the list/directory endpoint instead of the file-read endpoint
- Check the entry metadata (is_dir flag) returned by the listing API and disable download for directories in your UI
Example fix
// before
await client.read_workspace_file(path="docs/")
// after
entries = await client.list_workspace(path="docs/")
file_entry = next(e for e in entries if not e.is_dir)
await client.read_workspace_file(path=f"docs/{file_entry.name}") Defensive patterns
Strategy: validation
Validate before calling
listing = await client.list_workspace(path=parent_dir)
entry = next((e for e in listing if e.name == name), None)
if entry is None or entry.is_dir:
raise ValueError(f"{path} is not a readable workspace file")
content = await client.read_workspace_file(path=path) Prevention
- Always derive file paths from a directory listing rather than string concatenation
- Disable download buttons in the UI for entries with is_dir true
When it happens
Trigger: Calling GET on the workspace file-read endpoint (e.g. /workspace/file?path=docs or any path ending in /) where the path resolves to a folder inside the workspace. Also happens when a client builds a path from a listing and forgets to append a filename.
Common situations: UI file browser passing the currently selected folder instead of a file to the download button; hardcoded example paths like 'README' that are actually directories; off-by-one in path construction appending an empty filename segment.
Related errors
- host_workdir must be a directory.
- basedir must not be empty.
- BubblewrapWorkspaceManager currently requires share_net=True
- Bubblewrap workdir escapes basedir.
- workspace_id {workspace_id!r} escapes the workspace base dir
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/951819200317cde9.
Report an issue: GitHub.