{"record":{"id":"583e9b42fb093afa","repo":"infiniflow/ragflow","slug":"failed-to-create-remote-workspace-on-self-host","errorCode":null,"errorMessage":"Failed to create remote workspace on {self.host}: {stderr or stdout or 'unknown error'}","messagePattern":"Failed to create remote workspace on (.+?): (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/sandbox/providers/ssh.py","lineNumber":525,"sourceCode":"        else:\n            for key_cls in loaders:\n                try:\n                    return key_cls.from_private_key(io.StringIO(private_key_value), password=passphrase)\n                except Exception as exc:\n                    errors.append(str(exc))\n\n        raise SandboxProviderConfigError(\"Failed to load SSH private key. \" + \"; \".join(error for error in errors if error))\n\n    def _create_remote_workspace(self, client: paramiko.SSHClient) -> str:\n        base_dir = self.work_dir.rstrip(\"/\") or \"/tmp\"\n        template = posixpath.join(base_dir, \"ragflow-codeexec.XXXXXX\")\n        stdout, stderr, exit_code = self._run_remote_command(\n            client,\n            f\"mkdir -p {shlex.quote(base_dir)} && mktemp -d {shlex.quote(template)}\",\n            timeout=min(self.timeout, 10),\n        )\n        if exit_code != 0:\n            raise RuntimeError(f\"Failed to create remote workspace on {self.host}: {stderr or stdout or 'unknown error'}\")\n\n        remote_work_dir = stdout.strip().splitlines()[-1] if stdout.strip() else \"\"\n        if not remote_work_dir:\n            raise RuntimeError(\"Remote workspace creation did not return a path.\")\n        return remote_work_dir\n\n    def _upload_script(\n        self,\n        sftp: paramiko.SFTPClient,\n        remote_work_dir: str,\n        language: str,\n        code: str,\n        args_json: str,\n    ) -> tuple[str, str]:\n        if language == \"python\":\n            script_name = \"main.py\"\n            script_content = build_python_wrapper(code, args_json)\n        elif language in {\"javascript\", \"nodejs\"}:","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/providers/ssh.py#L507-L543","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"# before\nprovider.initialize({..., \"work_dir\": \"/var/lib/ragflow/work\"})  # not writable by ssh user\n\n# after\nprovider.initialize({..., \"work_dir\": \"/tmp\"})","handlingStrategy":"validation","validationCode":"import subprocess\nwork_dir = config.get(\"work_dir\", \"/tmp\")\nrc = subprocess.run(\n    [\"ssh\", f\"{config['username']}@{config['host']}\", f\"mkdir -p {work_dir} && mktemp -d {work_dir}/x.XXXXXX\"]\n).returncode\nif rc != 0:\n    raise RuntimeError(f\"SSH user cannot create workspace under {work_dir}\")","typeGuard":null,"tryCatchPattern":"try:\n    provider.create_instance(language=\"python\")\nexcept RuntimeError as e:\n    if \"Failed to create remote workspace\" in str(e):\n        raise RuntimeError(f\"fix permissions on work_dir; remote said: {e}\") from e","preventionTips":["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"],"tags":["ssh","filesystem","permissions","remote-workspace","configuration"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}