infiniflow/ragflow · error · RuntimeError

Artifact directory nesting exceeds {MAX_ARTIFACT_DEPTH} leve

Error message

Artifact directory nesting exceeds {MAX_ARTIFACT_DEPTH} levels: {relative_dir}

What it means

Raised while recursively collecting artifacts when directory depth exceeds MAX_ARTIFACT_DEPTH. The collector starts at depth 0 under the artifacts directory and recurses per directory level; the cap prevents runaway traversal of deep trees and guards the provider against path explosion.

Source

Thrown at agent/sandbox/providers/ucloud_agent_sandbox.py:416

        sandbox.files.write(script_path, script_content, request_timeout=self.timeout)
        return script_path, executable

    def _validate_output_size(self, stdout: str, stderr: str) -> None:
        """Reject combined standard output that exceeds the configured limit."""
        output_size = len(stdout.encode("utf-8")) + len(stderr.encode("utf-8"))
        if output_size > self.max_output_bytes:
            raise RuntimeError(f"UCloud Agent Sandbox execution output exceeded {self.max_output_bytes} bytes.")

    def _collect_artifacts(self, sandbox, artifacts_dir: str) -> list[dict[str, Any]]:
        """Collect allowed files from the execution artifact directory."""
        artifacts: list[dict[str, Any]] = []
        self._collect_artifacts_recursive(sandbox, artifacts_dir, "", artifacts, depth=0)
        return artifacts

    def _collect_artifacts_recursive(self, sandbox, current_dir: str, relative_dir: str, artifacts: list[dict[str, Any]], depth: int) -> None:
        """Traverse artifact directories while enforcing type, size, and depth limits."""
        if depth > MAX_ARTIFACT_DEPTH:
            raise RuntimeError(f"Artifact directory nesting exceeds {MAX_ARTIFACT_DEPTH} levels: {relative_dir}")
        sdk = _get_ucloud_sandbox_module()
        try:
            entries = sandbox.files.list(current_dir, depth=1, request_timeout=self.timeout)
        except sdk.FileNotFoundException:
            return
        for entry in sorted(entries, key=lambda item: item.path):
            name = posixpath.basename(entry.path)
            relative_path = posixpath.join(relative_dir, name) if relative_dir else name
            if entry.symlink_target is not None:
                raise RuntimeError(f"Artifact symlinks are not allowed: {relative_path}")
            if entry.type == sdk.FileType.DIR:
                self._collect_artifacts_recursive(sandbox, entry.path, relative_path, artifacts, depth + 1)
                continue
            if len(artifacts) >= self.max_artifacts:
                raise RuntimeError(f"UCloud Agent Sandbox execution produced more than {self.max_artifacts} artifacts.")
            if entry.size > self.max_artifact_bytes:
                raise RuntimeError(f"Artifact exceeds {self.max_artifact_bytes} bytes: {relative_path}")
            extension = os.path.splitext(name)[1].lower()

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Flatten artifact output — write files at shallow depths under the artifacts directory.
  2. Exclude deep trees (node_modules, .git, extracted archives) from the artifacts dir.
  3. If depth is legitimate, raise MAX_ARTIFACT_DEPTH in a patch or restructure output.
  4. Catch RuntimeError after execute and inform the user code that its artifact layout is too deep.

Example fix

# before
import shutil, os
os.makedirs("artifacts/a/b/c/.../z", exist_ok=True)  # 30+ levels -> RuntimeError

# after
os.makedirs("artifacts/out", exist_ok=True)
shutil.copy("deep/tree/file.txt", "artifacts/out/file.txt")
Defensive patterns

Strategy: try-catch

Validate before calling

# bound depth in the user code you dispatch
if "artifacts" in code and "os.makedirs" in code:
    # naive guard: reject unbounded recursive mkdir patterns before executing
    assert "while" not in code.split("makedirs")[-1][:60], "possible unbounded mkdir"

Type guard

def is_artifact_depth_error(exc: RuntimeError) -> bool:
    return "nesting exceeds" in str(exc)

Try / catch

try:
    result = provider.execute(inst, code)
except RuntimeError as e:
    if "nesting exceeds" in str(e):
        result = retry_with_flattened_artifacts(inst, code)  # e.g. add a pre-execution rewrite
    else:
        raise

Prevention

When it happens

Trigger: Executed code creating nested directories under the artifacts dir deeper than MAX_ARTIFACT_DEPTH (e.g. recursive mkdir loops, unpacked archives with deep paths, or accidental recursive copies).

Common situations: Code that unpacks a tarball with many nested levels; a script copying a directory into itself; build tools (node_modules-style nesting) writing into the artifacts folder.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/6ebd359503769e43. Report an issue: GitHub.