langchain-ai/deepagents · error · ValueError
suffix must be empty or a short extension such as .md
Error message
suffix must be empty or a short extension such as .md
What it means
`_validate_temp_artifact_suffix` checks the requested suffix against `_TEMP_ARTIFACT_SUFFIX_RE` (empty string or a short file extension like ".md") and raises `ValueError` if it doesn't match. This is called by `create_temp_artifact` to keep temp artifact filenames safe and predictable and to prevent path tricks via crafted suffixes.
Source
Thrown at libs/code/deepagents_code/auto_mode.py:1019
def _current_temp_artifacts(
state: Mapping[str, object], runtime: object, messages: Sequence[object]
) -> dict[str, AutoTempArtifact]:
thread_key = _thread_key(runtime)
turn_id = _latest_turn_id(messages)
if thread_key is None or turn_id is None:
return {}
return {
file_path: artifact
for file_path, artifact in _active_temp_artifacts(state).items()
if artifact["thread_key"] == thread_key and artifact["turn_id"] == turn_id
}
def _validate_temp_artifact_suffix(suffix: str) -> str:
if not _TEMP_ARTIFACT_SUFFIX_RE.fullmatch(suffix):
msg = "suffix must be empty or a short extension such as .md"
raise ValueError(msg)
return suffix
def _write_temp_artifact_bytes(file_descriptor: int, data: bytes) -> os.stat_result:
remaining = memoryview(data)
while remaining:
written = os.write(file_descriptor, remaining)
if written <= 0:
msg = "could not write the complete temporary artifact"
raise OSError(msg)
remaining = remaining[written:]
return os.fstat(file_descriptor)
def _allocate_temp_artifact(
content: str,
suffix: str,
*,View on GitHub (pinned to a1af029e6e)
Solutions
- Pass an empty string or a short single extension with a leading dot, e.g. suffix=".md".
- Normalize input filenames first: take only the final extension and lowercase it (pathlib.Path(name).suffix).
- Reject or strip directory components and multi-part extensions before calling.
- Catch ValueError to fall back to the default empty suffix if the original is unusable.
Example fix
// before
create_temp_artifact(name, suffix=filename) # suffix="report.tar.gz" -> ValueError
// after
suffix = pathlib.Path(filename).suffix.lower()
if len(suffix) > 5:
suffix = ""
create_temp_artifact(name, suffix=suffix) Defensive patterns
Strategy: validation
Validate before calling
import re
_SUFFIX_OK = re.compile(r"^(\.[A-Za-z0-9]+)?$")
def safe_suffix(value: str | None) -> str:
s = value or ""
if not _SUFFIX_OK.fullmatch(s) or len(s) > 5:
raise UsageError(f"unsupported suffix {s!r}; use '' or a short extension like '.md'")
return s
# call site
create_temp_artifact(name, suffix=safe_suffix(user_input)) Type guard
def _is_safe_suffix(value: object) -> TypeGuard[str]:
return isinstance(value, str) and re.fullmatch(r"(\.[A-Za-z0-9]+)?", value) is not None Try / catch
try:
path = create_temp_artifact(name, suffix=user_suffix)
except ValueError:
path = create_temp_artifact(name, suffix="") # fall back to default Prevention
- Derive suffixes with pathlib.Path(filename).suffix instead of passing whole filenames.
- Whitelist allowed extensions (.md, .txt, .json) in your own UI before calling create_temp_artifact.
- Strip any path components from user-supplied values; never embed '/' in a suffix.
- Cap extension length and normalize case before passing through.
When it happens
Trigger: Calling create_temp_artifact(..., suffix=...) with a value failing the regex: multi-part or long extensions (".tar.gz", ".markdown"), strings with slashes or dots in the wrong place ("/etc", "a.md"), or a suffix lacking a leading dot when one is required.
Common situations: Deriving the suffix from a user-supplied filename without normalizing it to a short extension; passing an entire filename as the suffix; joining a directory path into the suffix; passing None where the regex expects a string.
Related errors
- Provider name cannot be empty
- API key cannot be empty
- temporary artifact is not a regular file
- DiffStats counts cannot be negative, got additions={self.add
- Unknown external event kind: {self.kind!r}
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/1eb4e945df24402e.
Report an issue: GitHub.