ComposioHQ/composio · error · FileUploadPathNotAllowedError
Refusing to auto-upload "{attempted}": resolved path is not
Error message
Refusing to auto-upload "{attempted}": resolved path is not inside any directory in the configured `file_upload_dirs` allowlist. What it means
The resolved (symlink-followed, absolute) path of the file to auto-upload is not inside any directory listed in file_upload_dirs, so FileUploadPathNotAllowedError is raised — including the attempted, resolved, and allowlist paths for debugging. Component-boundary checks also apply (paths must stay within the allowed roots).
Source
Thrown at python/composio/utils/upload_dir_allowlist.py:203
[
f'Refusing to auto-upload "{attempted}": no upload directories are configured.',
"",
f"Path attempted: {attempted}",
f"Resolved to: {real_path}",
"",
"Automatic file upload during tool execution is locked down by default",
"to prevent a prompt-injected tool from exfiltrating server files",
"(source code, .env, SSH keys, etc.).",
_build_help_footer(allowlist),
]
)
)
for dir_entry in allowlist:
if is_inside_dir(real_path, resolve_root(dir_entry)):
return
raise FileUploadPathNotAllowedError(
"\n".join(
[
f'Refusing to auto-upload "{attempted}": resolved path is not inside any',
"directory in the configured `file_upload_dirs` allowlist.",
"",
f"Path attempted: {attempted}",
f"Resolved to: {real_path}",
_build_help_footer(allowlist),
]
)
)
View on GitHub (pinned to 64b1b85502)
Solutions
- Add the file's actual resolved directory to file_upload_dirs (print abs_path.resolve() from the error to see the truth)
- Move/copy the file inside an already-allowed directory before uploading
- Configure allowlist entries as absolute paths, or rooted at the same base the uploads use
- Beware symlinks: the check uses realpath, so link targets must also be inside the allowlist
Example fix
# before
Composio(api_key=KEY, file_upload_dirs=["/home/me/project"])
upload.from_path("/home/me/Desktop/report.pdf")
# after
Composio(api_key=KEY, file_upload_dirs=["/home/me/project", "/home/me/Desktop"])
# or: copy report.pdf into /home/me/project first Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def inside_allowlist(p, dirs):
rp = Path(p).resolve()
return any(rp.is_relative_to(Path(d).resolve()) for d in dirs) Try / catch
from composio.exceptions import FileUploadPathNotAllowedError
try:
upload.from_path(p)
except FileUploadPathNotAllowedError as e:
if "not inside any directory" in str(e):
p = copy_into_allowed_dir(p)
upload.from_path(p) Prevention
- Use absolute allowlist entries matching real upload roots
- Remember symlinks resolve to their target — include targets in the allowlist
- Copy out-of-bounds files into an allowed staging directory
When it happens
Trigger: Uploading a file outside every configured dir (e.g. allowlist has /home/me/project but the file is /home/me/Desktop/f.pdf); symlinks resolving outside the allowlist; path traversal via ../ escaping the root; allowlist entries that don't match how the path resolves (relative-vs-absolute mismatch).
Common situations: Allowlist configured with relative paths but uploads resolve elsewhere; project dir moved/renamed after client construction; symlinked uploads directory pointing to shared storage; CI checking out code to a different path than configured.
Related errors
- Refusing to auto-upload "{attempted}": no upload directories
- Refusing to auto-upload "${attempted}": no upload directorie
- Refusing to auto-upload "${attempted}": resolved path is not
- Unsafe path component: {e}
- Refusing to build a path from an empty or non-string {label}
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/df36398c817612ff.
Report an issue: GitHub.