infiniflow/ragflow · error · RuntimeError
Failed to create remote workspace on {self.host}: {stderr or
Error message
Failed to create remote workspace on {self.host}: {stderr or stdout or 'unknown error'} What it means
Raised as RuntimeError by SSHProvider._create_remote_workspace when the remote command 'mkdir -p <work_dir> && mktemp -d <work_dir>/ragflow-codeexec.XXXXXX' exits non-zero. This runs during instance creation and per-execution workspace setup; the message includes the host and the remote stdout/stderr. It signals the SSH session works but the remote filesystem rejects the workspace creation.
Source
Thrown at agent/sandbox/providers/ssh.py:525
else:
for key_cls in loaders:
try:
return key_cls.from_private_key(io.StringIO(private_key_value), password=passphrase)
except Exception as exc:
errors.append(str(exc))
raise SandboxProviderConfigError("Failed to load SSH private key. " + "; ".join(error for error in errors if error))
def _create_remote_workspace(self, client: paramiko.SSHClient) -> str:
base_dir = self.work_dir.rstrip("/") or "/tmp"
template = posixpath.join(base_dir, "ragflow-codeexec.XXXXXX")
stdout, stderr, exit_code = self._run_remote_command(
client,
f"mkdir -p {shlex.quote(base_dir)} && mktemp -d {shlex.quote(template)}",
timeout=min(self.timeout, 10),
)
if exit_code != 0:
raise RuntimeError(f"Failed to create remote workspace on {self.host}: {stderr or stdout or 'unknown error'}")
remote_work_dir = stdout.strip().splitlines()[-1] if stdout.strip() else ""
if not remote_work_dir:
raise RuntimeError("Remote workspace creation did not return a path.")
return remote_work_dir
def _upload_script(
self,
sftp: paramiko.SFTPClient,
remote_work_dir: str,
language: str,
code: str,
args_json: str,
) -> tuple[str, str]:
if language == "python":
script_name = "main.py"
script_content = build_python_wrapper(code, args_json)
elif language in {"javascript", "nodejs"}:View on GitHub (pinned to 554fb1133a)
Solutions
- Set work_dir to a directory the SSH user can write (default /tmp) — check with ssh user@host 'touch /tmp/x && rm /tmp/x'
- Fix remote permissions: install -d -o <sshuser> <work_dir> on the host
- Free disk space / raise the tmpfs size if mktemp failed on ENOSPC
- Check the stderr fragment embedded in the message — it carries the exact remote error
Example fix
# before
provider.initialize({..., "work_dir": "/var/lib/ragflow/work"}) # not writable by ssh user
# after
provider.initialize({..., "work_dir": "/tmp"}) Defensive patterns
Strategy: validation
Validate before calling
import subprocess
work_dir = config.get("work_dir", "/tmp")
rc = subprocess.run(
["ssh", f"{config['username']}@{config['host']}", f"mkdir -p {work_dir} && mktemp -d {work_dir}/x.XXXXXX"]
).returncode
if rc != 0:
raise RuntimeError(f"SSH user cannot create workspace under {work_dir}") Try / catch
try:
provider.create_instance(language="python")
except RuntimeError as e:
if "Failed to create remote workspace" in str(e):
raise RuntimeError(f"fix permissions on work_dir; remote said: {e}") from e Prevention
- Default work_dir to /tmp or another user-writable location
- Provision the workspace directory with correct ownership on the remote host
- Embed the remote stderr from the message in your alerts — it names the exact cause
When it happens
Trigger: work_dir config pointing to a directory the SSH user cannot create/write (permission denied); work_dir on a read-only filesystem; disk full (mktemp fails); SELinux/AppArmor denial; path with a non-directory component (e.g. /tmp/file/x).
Common situations: Setting work_dir to /var/lib/app owned by root while connecting as a non-root user; containers with read-only root filesystems where work_dir defaults under /tmp but tmpfs is size-limited; shared hosts with strict quotas.
Related errors
- Failed to load configured SSH known_hosts file.
- Invalid SSH provider configuration.
- Failed to create remote artifacts directory: {stderr or stdo
- SSH connectivity check failed on {self.username}@{self.host}
- Failed to connect to SSH host {self.username}@{self.host}:{s
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/583e9b42fb093afa.
Report an issue: GitHub.