infiniflow/ragflow · error · RuntimeError

UCloud Agent Sandbox execution produced more than {self.max_

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.

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)

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.