{"record":{"id":"00eba60d930befd5","repo":"can1357/oh-my-pi","slug":"failed-to-mount-target-suffix","errorCode":null,"errorMessage":"Failed to mount ${target}${suffix}","messagePattern":"Failed to mount (.+?)(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/ssh/sshfs-mount.ts","lineNumber":136,"sourceCode":"\tawait Promise.all([ensureDir(REMOTE_DIR), ensureDir(mountPath)]);\n\n\tif (await isMounted(mountPath)) {\n\t\tif (!registered) {\n\t\t\tregistered = true;\n\t\t\tpostmortem.register(\"sshfs-cleanup\", unmountAll);\n\t\t}\n\t\tmountedPaths.add(mountPath);\n\t\treturn mountPath;\n\t}\n\n\tconst target = `${buildSshTarget(host.username, host.host)}:${remotePath}`;\n\tconst args = buildSshfsArgs(host);\n\tconst result = await $`sshfs ${args} ${target} ${mountPath}`.nothrow();\n\n\tif (result.exitCode !== 0) {\n\t\tconst detail = result.stderr.toString().trim();\n\t\tconst suffix = detail ? `: ${detail}` : \"\";\n\t\tthrow new Error(`Failed to mount ${target}${suffix}`);\n\t}\n\n\tmountedPaths.add(mountPath);\n\treturn mountPath;\n}\n\nexport async function unmountRemote(host: SSHConnectionTarget): Promise<boolean> {\n\tconst mountPath = getMountPath(host);\n\tif (!(await isMounted(mountPath))) {\n\t\tmountedPaths.delete(mountPath);\n\t\treturn false;\n\t}\n\n\tconst success = await unmountPath(mountPath);\n\tif (success) {\n\t\tmountedPaths.delete(mountPath);\n\t}\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/ssh/sshfs-mount.ts#L118-L154","documentation":"mountRemote runs `sshfs <args> <target> <mountPath>` and throws this error when sshfs exits non-zero, appending sshfs's stderr. The failure is in the sshfs tool itself — which wraps both SSH connectivity and FUSE mounting — so causes range from auth/network issues to missing FUSE support.","triggerScenarios":"sshfs not installed or lacking setuid/fusermount permissions, mount point already in use or nonempty, remote auth failure, OS without /dev/fuse (containers without --privileged/--device /dev/fuse).","commonSituations":"Running inside a Docker container/CI without FUSE access, macOS without macFUSE installed, remote host unreachable or key rejected, stale mount at the target path, sshfs not installed at all.","solutions":["Read the appended stderr detail for the specific sshfs cause","Install FUSE support: Linux `apt install sshfs fuse3`; macOS install macFUSE; containers need --device /dev/fuse --cap-add SYS_ADMIN (or fusermount3 setup)","Verify plain `ssh <target>` works first; fix auth/host issues before mounting","Unmount stale mounts: fusermount -u <mountPath> and retry","Ensure the mount point exists and is empty"],"exampleFix":"# before (in container)\n$ omp ssh mount prod:/data /mnt/data   # Failed to mount: fuse device not found\n# after\n$ docker run --device /dev/fuse --cap-add SYS_ADMIN ...\n$ sudo apt-get install -y sshfs fuse3\n$ omp ssh mount prod:/data /mnt/data","handlingStrategy":"validation","validationCode":"import { $ } from \"bun\";\n// preflight: sshfs present, FUSE device available, target reachable\nconst hasSshfs = await $`which sshfs`.quiet().nothrow();\nconst fuseDev = await fs.stat(\"/dev/fuse\").catch(() => null);\nif (hasSshfs.exitCode !== 0 || !fuseDev) throw new Error(\"sshfs/FUSE unavailable: install sshfs + fuse3 (container: --device /dev/fuse)\");","typeGuard":null,"tryCatchPattern":"try {\n  const mp = await mountRemote(host);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Failed to mount \")) {\n    const detail = err.message.split(\": \").slice(1).join(\": \");\n    if (/fusermount|fuse/i.test(detail)) console.error(\"FUSE not available — run privileged or install fuse3\");\n    if (/Permission denied|publickey/i.test(detail)) console.error(\"Fix ssh auth before mounting\");\n    await $`fusermount -u ${mountPath}`.quiet().nothrow(); // clear stale mount\n  }\n  throw err;\n}","preventionTips":["Install sshfs + fuse3 on hosts that mount; macFUSE on macOS","Grant containers /dev/fuse and SYS_ADMIN (or use unprivileged user namespaces)","Verify `ssh <target> true` before mounting","fusermount -u stale mount points before remounting"],"tags":["ssh","sshfs","mount","fuse","filesystem"],"backgroundTag":"sshfs-mount-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}