ComposioHQ/composio · error · SensitiveFilePathBlockedError
Refusing to upload: {reason}. Set sensitive_file_upload_prot
Error message
Refusing to upload: {reason}. Set sensitive_file_upload_protection=False on Composio if you must (not recommended), or use a copy outside sensitive locations. What it means
Raised by assert_safe_local_file_upload_path when the path being uploaded falls inside a known-sensitive location (SSH keys, .env files, credentials, dotfiles, etc.), guarded by _get_block_reason. It's a deliberate guardrail: Composio refuses to auto-upload files from sensitive paths unless the protection is explicitly disabled on the Composio client via sensitive_file_upload_protection=False.
Source
Thrown at python/composio/utils/sensitive_file_upload_paths.py:98
additional_deny_segments: t.Optional[t.Sequence[str]] = None,
) -> bool:
return _get_block_reason(file_path, additional_deny_segments) is not None
def assert_safe_local_file_upload_path(
file_path: t.Union[str, Path],
*,
enabled: bool = True,
additional_deny_segments: t.Optional[t.Sequence[str]] = None,
) -> None:
"""Raise SensitiveFilePathBlockedError if *file_path* matches the denylist."""
if not enabled:
return
reason = _get_block_reason(file_path, additional_deny_segments)
if reason:
from composio.exceptions import SensitiveFilePathBlockedError
raise SensitiveFilePathBlockedError(
f"Refusing to upload: {reason}. "
"Set sensitive_file_upload_protection=False on Composio if you must "
"(not recommended), or use a copy outside sensitive locations."
)
View on GitHub (pinned to 64b1b85502)
Solutions
- Copy the file to a non-sensitive location (e.g. /tmp/scratch/) and upload the copy, excluding secrets
- If the block is a false positive and you accept the risk, construct Composio(..., sensitive_file_upload_protection=False) — not recommended
- Check for symlinks: realpath the upload path and confirm it isn't resolving into a sensitive directory
- Audit the file for real secrets before overriding the guard
Example fix
# before
composio.tools.upload("~/.ssh/id_rsa")
# after
import shutil
tmp = "/tmp/id_rsa_copy"
shutil.copyfile(os.path.expanduser("~/.ssh/id_rsa"), tmp)
composio.tools.upload(tmp) Defensive patterns
Strategy: validation
Validate before calling
from composio.utils.sensitive_file_upload_paths import _get_block_reason
def safe_to_upload(path, extra=None):
return _get_block_reason(path, extra or tuple()) is None Try / catch
from composio.exceptions import SensitiveFilePathBlockedError
try:
composio.tools.upload(p)
except SensitiveFilePathBlockedError as e:
p = copy_to_scratch(p)
composio.tools.upload(p) Prevention
- Stage uploads from a neutral scratch directory, never from credential dirs
- realpath() upload paths to expose symlinked sensitive targets
- Keep secrets out of directories agents can read; never disable the guard reflexively
When it happens
Trigger: Calling a file-upload API whose path resolves into ~/.ssh/, .aws/, a directory containing .env, a dotfile config, or other deny-listed segments; also triggered when the real path (after symlink resolution) lands in a sensitive directory even if the given path looks benign.
Common situations: Agents asked to "attach the .env" or upload a workspace containing secrets; symlinked project dirs pointing into home/config areas; CI pipelines uploading from credential-bearing directories; defaults enabled on newer SDK versions surprising existing code.
Related errors
- Refusing to upload: ${reason}. ${remediation}
- Refusing to fetch a malformed URL
- Refusing to fetch a non-http(s) URL (scheme "${url.protocol}
- Refusing to auto-upload "${attempted}": the file does not ex
- Refusing to auto-upload "${attempted}": no upload directorie
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/4cf89b1edd708e65.
Report an issue: GitHub.