infiniflow/ragflow · error · RuntimeError

UCloud Agent Sandbox execution produced more than

Error message

UCloud Agent Sandbox execution produced more than {self.max_artifacts} artifacts.

What it means

Raised during artifact collection when the number of collected files would exceed `max_artifacts` (default 20). The check is `len(artifacts) >= self.max_artifacts` before appending each new file, so the 21st default artifact (files are traversed in sorted order) triggers it, discarding the whole execution result.

Solutions

  1. Write only the important outputs to artifacts; keep count at or under the cap (default 20).
  2. Bundle many files into one artifact (zip/tar) — subject to extension and size policy.
  3. Raise `max_artifacts` in the provider config for legitimate bulk-output workloads.
  4. Catch the RuntimeError and report which execution over-produced artifacts.

Example fix

# before
for i, item in enumerate(items):
    open(f"artifacts/item_{i}.json", "w").write(...)  # 500 items -> RuntimeError

# after
import json
open("artifacts/items.json", "w").write(json.dumps(items))
Defensive patterns

Strategy: validation

Validate before calling

max_artifacts = int(conf.get("max_artifacts", 20))
# when generating code, cap writes: emit one bundle instead of N files
guided_code = (
    "import json\n"
    f"assert len(outputs) <= {max_artifacts}, 'too many artifacts'\n"
    "open('artifacts/outputs.json', 'w').write(json.dumps(outputs))\n"
)

Type guard

def is_artifact_count_error(exc: RuntimeError) -> bool:
    return "more than" in str(exc) and "artifacts" in str(exc)

Try / catch

try:
    result = provider.execute(inst, code)
except RuntimeError as e:
    if "more than" in str(e) and "artifacts" in str(e):
        result = provider.execute(inst, bundle_artifacts_version(code))
    else:
        raise

Prevention

When it happens

Trigger: Executed code writing more than max_artifacts files into the artifacts directory — e.g. loops emitting per-item files, batch exports, or unpacked archives with many entries.

Common situations: Default cap of 20 too small for batch jobs writing one file per record; archive unpacking flooding the dir; users unaware that artifacts are meant to be a small curated set, not bulk storage.

Related errors


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

Appendix: source

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

    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()
            if extension not in ALLOWED_ARTIFACT_EXTENSIONS:
                raise RuntimeError(f"Unsupported artifact type: {relative_path}")
            content = bytes(sandbox.files.read(entry.path, format="bytes", request_timeout=self.timeout))
            artifacts.append(
                {
                    "name": relative_path,
                    "content_b64": base64.b64encode(content).decode("ascii"),
                    "mime_type": mimetypes.guess_type(name)[0] or "application/octet-stream",
                    "size": entry.size,
                }
            )

    def _safe_kill(self, sandbox) -> None:
        """Best-effort terminate a remote sandbox during cleanup."""
        try:

View on GitHub (pinned to 554fb1133a)