langchain-ai/deepagents · error · OSError

temporary artifact provenance is invalid

Error message

temporary artifact provenance is invalid

What it means

Raised by `_delete_temp_artifact_file` when the basename of the artifact's recorded `file_path` does not start with the library's temp-artifact prefix. This is a safety gate: `delete_temp_artifact` will only unlink files the library itself created (named with `_TEMP_ARTIFACT_PREFIX`), never arbitrary paths.

Source

Thrown at libs/code/deepagents_code/auto_mode.py:1116

    return Command(
        update={
            "messages": [
                ToolMessage(
                    content=content,
                    name=tool_name,
                    tool_call_id=tool_call_id,
                    status="error" if error else "success",
                )
            ]
        }
    )


def _delete_temp_artifact_file(artifact: AutoTempArtifact) -> None:
    file_path = Path(artifact["file_path"])
    if not file_path.name.startswith(_TEMP_ARTIFACT_PREFIX):
        msg = "temporary artifact provenance is invalid"
        raise OSError(msg)
    file_stat = file_path.lstat()
    if (
        not stat.S_ISREG(file_stat.st_mode)
        or file_stat.st_dev != artifact["file_device"]
        or file_stat.st_ino != artifact["file_inode"]
    ):
        msg = "temporary artifact identity changed"
        raise OSError(msg)
    file_path.unlink()


def _summarize_value(key: str, value: object, *, depth: int = 0) -> object:
    if depth >= _MAX_ARGUMENT_DEPTH:
        return "[nested value omitted]"
    if _SECRET_KEY_RE.search(key):
        return "[redacted credential value]"
    if key.lower() in {"content", "new_string", "old_string", "new_str"} and isinstance(
        value, str

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Only pass `AutoTempArtifact` dicts returned by `create_temp_artifact`; never hand-construct `file_path`
  2. If artifacts were persisted across a library upgrade, re-create them with the current version instead of deleting stale records
  3. Check state for corrupted or edited artifact entries and remove them without calling delete
  4. Clean up stray files manually if the artifact record is unrecoverable
Defensive patterns

Strategy: type-guard

Validate before calling

from pathlib import Path
from deepagents_code.auto_mode import _TEMP_ARTIFACT_PREFIX

def is_safe_artifact(artifact) -> bool:
    return Path(artifact["file_path"]).name.startswith(_TEMP_ARTIFACT_PREFIX)

Type guard

def is_library_created_artifact(artifact: dict) -> bool:
    path = artifact.get("file_path")
    return isinstance(path, str) and Path(path).name.startswith(_TEMP_ARTIFACT_PREFIX)

Try / catch

try:
    delete_temp_artifact(artifact)
except OSError as exc:
    if "provenance is invalid" in str(exc):
        drop_stale_record_without_unlink()
    else:
        raise

Prevention

When it happens

Trigger: Calling `delete_temp_artifact` with an `AutoTempArtifact` whose `file_path` was tampered with, hand-constructed, or deserialized from an older/foreign format — anything where the filename lacks the reserved prefix.

Common situations: Persisting artifacts to state and loading them after a library upgrade that renamed the temp prefix; manually building an `AutoTempArtifact` in tests pointing at a normal path; a hostile actor editing state to point deletion at an arbitrary file (the check is the defense).

Related errors


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