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 during artifact collection when the recursive directory walk under artifacts/ exceeds MAX_ARTIFACT_DEPTH (16 levels). The guard exists to bound traversal of untrusted, potentially pathological directory trees (including symlink-loop constructs) produced by executed code.
Source
Thrown at agent/sandbox/providers/tenki.py:446
raise RuntimeError(f"Unsupported language for Tenki provider: {language}")
script_path = posixpath.join(remote_work_dir, script_name)
sandbox.fs.write_text(script_path, script_content)
return script_path, [executable, script_path]
def _validate_output_size(self, stdout: str, stderr: str) -> None:
output_size = len((stdout or "").encode("utf-8")) + len((stderr or "").encode("utf-8"))
if output_size > self.max_output_bytes:
raise RuntimeError(f"Tenki execution output exceeded {self.max_output_bytes} bytes.")
def _collect_artifacts(self, sandbox, artifacts_dir: str) -> list[dict[str, Any]]:
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:
if depth > MAX_ARTIFACT_DEPTH:
raise RuntimeError(f"Artifact directory nesting exceeds {MAX_ARTIFACT_DEPTH} levels: {relative_dir}")
errors = self._tenki_errors()
try:
entries = sandbox.fs.list(current_dir)
except errors.FileNotFoundError:
return
except FileNotFoundError:
return
# fs.list returns each entry's basename in `.path`, not an absolute
# path, so join it onto the directory being listed.
for entry in sorted(entries, key=lambda item: item.path):
name = posixpath.basename(entry.path)
remote_path = posixpath.join(current_dir, name)
relative_path = posixpath.join(relative_dir, name) if relative_dir else name
# Reject symlinks. `is_symlink` is not populated by every SDK
# release, so also inspect the stat mode bits as the reliable check.View on GitHub (pinned to 554fb1133a)
Solutions
- Fix the script to flatten or limit artifact directory depth (keep outputs at the top level of artifacts/).
- Write only final result files into artifacts/, not source trees or dependency directories.
- If legitimate output genuinely needs more nesting, raise MAX_ARTIFACT_DEPTH — but treat depth blowups as a code smell first.
Example fix
# before
# script: for i in range(100): os.makedirs(f'artifacts/{"d/"*i}x')
# after
# script: os.makedirs('artifacts', exist_ok=True); shutil.copy(result, 'artifacts/result.csv') Defensive patterns
Strategy: validation
Validate before calling
# in generated code, keep artifacts flat
# depth check helper the script can run:
# for root, dirs, files in os.walk('artifacts'):
# assert root.count(os.sep) - 'artifacts'.count(os.sep) <= 16 Try / catch
try:
result = provider.execute_code(instance_id, code)
except RuntimeError as exc:
if "nesting exceeds" in str(exc):
result = provider.execute_code(instance_id, flattened_artifacts_version(code))
else:
raise Prevention
- Generate scripts that write outputs directly under artifacts/, never deep trees or extracted archives.
- Treat depth blowups as suspicious output from untrusted code.
When it happens
Trigger: User script creates nested directories deeper than 16 levels inside the artifacts dir (e.g. a loop doing os.makedirs('a/'*100)), or a directory structure with cycles that the symlink rejection did not prune before depth accrues.
Common situations: LLM-generated code copying deep node_modules-style trees into artifacts, archive extraction with deeply nested paths, or adversarial code trying to exhaust the walker.
Related errors
- Artifact symlinks are not allowed: {relative_path}
- Tenki execution produced more than {self.max_artifacts} arti
- Artifact exceeds {self.max_artifact_bytes} bytes: {relative_
- Artifact symlinks are not allowed: {path.name}
- Local execution produced more than {self.max_artifacts} arti
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/3b8bb872e95085f6.
Report an issue: GitHub.