infiniflow/ragflow · error · RuntimeError

Unsupported artifact entry: {relative_path}

Error message

Unsupported artifact entry: {relative_path}

What it means

Raised as RuntimeError when an artifacts-dir entry is neither a symlink, directory, nor regular file (stat.S_ISREG fails) — e.g. FIFOs, sockets, device nodes. The collector can only package regular files, and special entries could hang a read (FIFO) or escape the size/extension checks, so they abort collection. Mode comes from listdir_attr with an lstat fallback.

Source

Thrown at agent/sandbox/providers/ssh.py:646

            return

        for entry in sorted(entries, key=lambda item: item.filename):
            name = entry.filename
            remote_path = posixpath.join(current_dir, name)
            relative_path = posixpath.join(relative_dir, name) if relative_dir else name
            mode = entry.st_mode
            if mode is None:
                mode = sftp.lstat(remote_path).st_mode
            if mode is None:
                raise RuntimeError(f"Unable to determine artifact entry type: {relative_path}")

            if stat.S_ISLNK(mode):
                raise RuntimeError(f"Artifact symlinks are not allowed: {relative_path}")
            if stat.S_ISDIR(mode):
                self._collect_artifacts_recursive(sftp, remote_path, relative_path, artifacts)
                continue
            if not stat.S_ISREG(mode):
                raise RuntimeError(f"Unsupported artifact entry: {relative_path}")

            if len(artifacts) >= self.max_artifacts:
                raise RuntimeError(f"SSH execution produced more than {self.max_artifacts} artifacts.")

            size = int(entry.st_size or 0)
            if size > self.max_artifact_bytes:
                raise RuntimeError(f"Artifact exceeds {self.max_artifact_bytes} bytes: {relative_path}")

            ext = os.path.splitext(name)[1].lower()
            if ext not in ALLOWED_ARTIFACT_EXTENSIONS:
                raise RuntimeError(f"Unsupported artifact type: {relative_path}")

            with sftp.file(remote_path, "rb") as artifact_file:
                content = artifact_file.read()

            artifacts.append(
                {
                    "name": relative_path,

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Point artifact output at a dedicated clean directory; keep runtime scratch (sockets, fifos) outside it
  2. Clean special files before finishing: os.remove() any FIFOs/sockets created by the code
  3. Configure work_dir so no special nodes from the system fall under the artifacts tree

Example fix

# before (sandboxed code)
os.mkfifo('artifacts/pipe')  # collection later aborts

# after (sandboxed code)
import multiprocessing
mp.set_start_method('fork')  # or keep sockets out of the artifacts dir
open('artifacts/result.txt', 'w').write('done')
Defensive patterns

Strategy: try-catch

Validate before calling

# inside sandboxed code, before returning
import os, stat
for root, _, files in os.walk(artifacts_dir):
    for f in files:
        p = os.path.join(root, f)
        if not stat.S_ISREG(os.lstat(p).st_mode):
            os.remove(p)

Try / catch

try:
    artifacts = provider.collect_artifacts(instance_id, artifacts_dir)
except RuntimeError as e:
    if "Unsupported artifact entry" in str(e):
        log.warning("special file in artifacts dir; cleaning and retrying")
        raise

Prevention

When it happens

Trigger: Sandboxed code mkfifo()-ing a file in the artifacts directory; a crashed process leaving a unix socket in the workspace; /dev or other special nodes bind-mounted into the workspace.

Common situations: Generated code using multiprocessing (which creates semaphore/socket files) with artifacts dir = working dir; debug tooling leaving FIFOs; misconfigured containers mounting device nodes under work_dir.

Related errors


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