windmill-labs/windmill · error
file path must refer to a file.
Error message
file path must refer to a file.
What it means
Thrown by the Windmill CLI's `resource push` command when the local path given to push does not point to a regular file on disk. After validating the remote path, the CLI calls stat(filePath) and requires the entry to be a file (isFile()); directories, sockets, symlinks-to-directories, or nonexistent paths fail (stat itself rejecting surfaces as ENOENT, but a directory hits this explicit error).
Source
Thrown at cli/src/commands/resource/resource.ts:177
...localResource,
...(wsSpecific !== undefined ? { ws_specific: wsSpecific } : {}),
},
});
}
}
type PushOptions = GlobalOptions;
async function push(opts: PushOptions, filePath: string, remotePath: string) {
const workspace = await resolveWorkspace(opts);
await requireLogin(opts);
if (!validatePath(remotePath)) {
return;
}
const fstat = await stat(filePath);
if (!fstat.isFile()) {
throw new Error("file path must refer to a file.");
}
log.info(colors.bold.yellow("Pushing resource..."));
await pushResource(
workspace.workspaceId,
remotePath,
undefined,
parseFromFile(filePath),
filePath // Pass the local file path for branch-specific inline content resolution
);
log.info(colors.bold.underline.green(`Resource ${remotePath} pushed`));
}
async function list(opts: GlobalOptions & { json?: boolean }) {
if (opts.json) log.setSilent(true);
const workspace = await resolveWorkspace(opts);
await requireLogin(opts);View on GitHub (pinned to e474e8803c)
Solutions
- Pass the actual resource YAML file path (e.g. ./myres.resource.yaml) instead of a directory
- If it's a symlink, point at or link the real file
- Verify with `ls -l <path>` / `test -f <path>` that the argument is a regular file before pushing
Example fix
// before wmill resource push u/admin/myres ./resources/ // after wmill resource push u/admin/myres ./resources/myres.resource.yaml
Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from 'fs';
const st = statSync(localPath); // throws ENOENT early if missing
if (!st.isFile()) {
throw new Error(`--path must be a .resource.yaml file, got: ${localPath}`);
} Type guard
import { Stats, statSync } from 'fs';
async function isRegularFile(p: string): Promise<boolean> {
try { return (await import('fs/promises')).default.stat(p).then(s => s.isFile()); } catch { return false; }
}
// sync variant:
function isFile(p: string): boolean { try { return statSync(p).isFile(); } catch { return false; } } Try / catch
try {
await wmill.resource.push(remotePath, localPath);
} catch (e) {
if ((e as Error).message === 'file path must refer to a file.') {
console.error(`${localPath} is a directory or not a regular file; pass the .resource.yaml file itself`);
} else throw e;
} Prevention
- Pass the exact `.resource.yaml` file path, never its containing directory
- Check paths with `test -f "$path"` in shell scripts before pushing
- Beware symlinks: stat follows them; link to files, not directories
- Let tab-completion finish at the file, and re-read the command before running
When it happens
Trigger: Running `wmill resource push <remote> <localPath>` where localPath is a directory (e.g. passing the containing folder instead of the `.resource.yaml` file), or a special/non-regular file. Note: a nonexistent path throws from stat with ENOENT before reaching this check.
Common situations: Passing a directory by mistake or relying on shell glob expansion that yielded a directory; pointing at a symlink that resolves to a directory; scripting that interpolates an empty or wrong variable so the path ends up as '.' or a folder; copy-pasting a folder path instead of the resource YAML file.
Related errors
- file path must refer to a file.
- File already exists: + filePath
- File already exists: + filePath
- File not found: ${filePath}
- Workspace folder not found, are you in the right directory?
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/23dfb595fa818e78.
Report an issue: GitHub.