can1357/oh-my-pi · error
ssh://: ${remotePath} is not a regular file (FIFO, socket, o
Error message
ssh://: ${remotePath} is not a regular file (FIFO, socket, or device); ssh:// reads UTF-8 text files only — use `bash` with a remote SSH command for special files What it means
Before reading, the handler stats the remote path; a path classified as `kind === "other"` (FIFO, socket, device) is rejected outright. Reading such a file would hang (FIFO with no writer) or stream unboundedly (e.g. /dev/zero), so it must fail fast. ssh:// only materializes regular UTF-8 text files.
Source
Thrown at packages/coding-agent/src/internal-urls/ssh-protocol.ts:291
}
const target = await resolveTarget(url, context?.cwd);
const remotePath = remotePathFromUrl(url);
// Classify before reading. A FIFO with no writer would block `head` until the
// timeout, and a device (e.g. /dev/zero) would stream the whole probe, so a
// special file must fail fast. Only a regular file is read; a directory lists.
// `missing`/stat-failure falls through to the read so its original remote stderr
// (e.g. "No such file or directory") still surfaces.
let kind: RemotePathKind | undefined;
try {
kind = await statRemotePath(target, remotePath, { signal: context?.signal });
} catch {
// stat failed (host/connection issue) — fall through; the read gives a clearer error.
}
if (kind === "directory") {
return this.#resolveDirectory(target, remotePath, url, context?.signal, context?.skipDirectoryListing);
}
if (kind === "other") {
throw new Error(
`ssh://: ${remotePath} is not a regular file (FIFO, socket, or device); ssh:// reads UTF-8 text files only — use \`bash\` with a remote SSH command for special files`,
);
}
const fileResult = await readRemoteFile(target, remotePath, {
maxBytes: SSH_TEXT_MAX_BYTES,
signal: context?.signal,
});
if (fileResult.truncated) {
throw new Error(
`ssh://: ${remotePath} exceeds the 1 MiB limit; ssh:// supports text files up to 1 MiB — use an sshfs mount for larger files`,
);
}
const content = decodeUtf8Text(fileResult.bytes);
if (content === null) {
throw new Error(
`ssh://: ${remotePath} is a binary or non-UTF-8 file; ssh:// supports UTF-8 text only — use \`bash\` with a remote SSH command or an \`sshfs\` mount`,
);
}View on GitHub (pinned to 9690622007)
Solutions
- Run a remote command via the bash tool instead: `ssh prod 'cat /dev/...'` or read the device through a command that produces bounded text
- Point the URL at a regular file on the remote host
- If the special file proxies data, capture it to a regular file first (e.g. `ssh prod 'cmd > /tmp/out.txt'`) and read that
Example fix
// before
resolve('ssh://prod/dev/zero')
// after
bash('ssh prod head -c 1024 /dev/zero | xxd') // special files via remote command Defensive patterns
Strategy: validation
Validate before calling
const kind = await statRemotePath(target, remotePath, { signal });
if (kind === 'other') throw new Error(`${remotePath} is a FIFO/socket/device; use bash with a remote command`); Type guard
function isRegularRemoteFile(k: RemotePathKind | undefined): boolean { return k === undefined || k === 'file'; } Try / catch
try {
const res = await handler.resolve(url, ctx);
} catch (e) {
if (e instanceof Error && e.message.includes('is not a regular file')) {
// fall back to `bash` with a remote ssh command for the special file
} else throw e;
} Prevention
- Don't point ssh:// at /dev/*, sockets, or FIFOs — reserve it for regular text files
- Stat remote paths before reading when the path comes from dynamic discovery
- Route special-file needs through remote commands (head/cat with limits) instead
When it happens
Trigger: Resolving an ssh:// URL to a FIFO, Unix socket, or device node, e.g. `ssh://prod/dev/zero` or `ssh://prod/run/some.sock`; the remote `stat` classified the path as neither directory nor regular file.
Common situations: Pointing the read tool at device files or IPC sockets; probing named pipes used by services; accidentally targeting /proc or /sys pseudo-files.
Related errors
- unknown filetype: {ft_debug}
- imageUrls exposure "ssh" requires imageUrls.publicBaseUrl
- imageUrls exposure "ssh" requires imageUrls.sshTarget
- ssh reverse forward to ${config.sshTarget} exited with code
- SFTP password injection is unsupported by the shared SSH tra
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e7a263e086fa8735.
Report an issue: GitHub.