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

  1. Pass an empty string or a short single extension with a leading dot, e.g. suffix=".md".
  2. Normalize input filenames first: take only the final extension and lowercase it (pathlib.Path(name).suffix).
  3. Reject or strip directory components and multi-part extensions before calling.
  4. 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

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


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/1eb4e945df24402e. Report an issue: GitHub.