windmill-labs/windmill · error · Error
Cannot push a script metadata file, point to the script cont
Error message
Cannot push a script metadata file, point to the script content file instead (.py, .ts, .go|.sh)
What it means
The wmill script push command expects the path to a script CONTENT file (.py, .ts, .go, .sh, etc.). Passing a script metadata file (.script.json or .script.yaml) — which only holds settings, not code — is rejected upfront with this error, guiding the user to the correct file.
Source
Thrown at cli/src/commands/script/script.ts:191
return;
}
// A dbt project's descriptor is optional, so the one content path a
// descriptor-less project has is deliberately not on disk. The project beside
// it is what says the script is real.
const absentDescriptor = await stat(filePath).then(
() => false,
(e) => isMissingDbtDescriptor(filePath, e)
);
if (!absentDescriptor) {
const fstat = await stat(filePath);
if (!fstat.isFile()) {
throw new Error("file path must refer to a file.");
}
}
if (filePath.endsWith(".script.json") || filePath.endsWith(".script.yaml")) {
throw Error(
"Cannot push a script metadata file, point to the script content file instead (.py, .ts, .go|.sh)"
);
}
if (isFileResource(filePath) || isFilesetResource(filePath)) {
throw Error(
"Cannot push a file/fileset resource content file as a script, push its .resource.yaml with 'wmill resource push' instead"
);
}
await requireLogin(opts);
// Warn about metadata state before pushing
try {
const content = await readScriptContent(filePath);
const remotePath = removeExtensionToPath(filePath).replaceAll(SEP, "/");
const contentHash = await computePushMetadataHash(filePath, content);
const conf = await readLockfile();View on GitHub (pinned to e474e8803c)
Solutions
- Point the push at the content file instead: `wmill script push path/to/script.py --path u/user/my_script` (the metadata lives alongside as .script.json and is applied automatically).
- If pushing a whole directory of scripts, use `wmill script sync` or filter out *.script.json/*.script.yaml from your push script.
- If you only have the metadata file, recover/regenerate the content file — the metadata does not contain the code.
Example fix
# before wmill script push u/user/my_script.script.json # after wmill script push u/user/my_script.ts --path u/user/my_script --summary "..."
Defensive patterns
Strategy: validation
Validate before calling
const CONTENT_RE = /\.(py|ts|go|sh|sql|billing|php|rs|nu|jsx|tsx|flow|yaml\.flow)$/;
if (filePath.endsWith('.script.json') || filePath.endsWith('.script.yaml')) {
filePath = filePath.replace(/\.script\.(json|yaml)$/, ''); // derive content file
}
if (!CONTENT_RE.test(filePath)) throw new Error(`not a script content file: ${filePath}`); Prevention
- In push loops, filter out *.script.json and *.script.yaml glob patterns.
- Always pass the code file (.py/.ts/...) to `wmill script push`; metadata is applied automatically.
- Tab-complete to the extension you intend before running push.
When it happens
Trigger: Running `wmill script push path/to/script.script.json` or `... .script.yaml` — detected in push() by the filePath.endsWith checks before any login/API work.
Common situations: Syncing a repo and pushing every file including metadata files; confusing the metadata file (used by `wmill script` sync/to-json tooling) with the code file; tab-completion picking the .script.json instead of the .py/.ts sibling.
Related errors
- Cannot push a file/fileset resource content file as a script
- pointerErrors.join("\n")
- Invalid native trigger file path: ${filePath}. Expected form
- Warning: You are not an admin or member of 'wm_deployers'. T
- ${msg}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/654bee5d108ce75c.
Report an issue: GitHub.