windmill-labs/windmill · error · Error

Cannot push a file/fileset resource content file as a script

Error message

Cannot push a file/fileset resource content file as a script, push its .resource.yaml with 'wmill resource push' instead

What it means

wmill script push rejects files that are resource CONTENT files (file or fileset resource payloads). These belong to file/fileset resources, not scripts; the CLI tells you to push the accompanying .resource.yaml metadata via `wmill resource push` instead.

Source

Thrown at cli/src/commands/script/script.ts:197

  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();
    const hasLockEntry = conf.locks && (conf.locks[remotePath] !== undefined || conf.locks[`${remotePath}.ts`] !== undefined);
    if (!hasLockEntry) {
      log.warn(colors.yellow(
        `No metadata generated yet for ${filePath}. Run 'wmill generate-metadata' to generate schema and lock.`
      ));
    } else if (!(await checkifMetadataUptodate(remotePath, contentHash, conf))) {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Push the resource metadata instead: `wmill resource push path/to/file.resource.yaml` — the content file is referenced/uploaded by that flow.
  2. Exclude *.resource.yaml content/asset files from your script push loop or directory sync.
  3. If the file genuinely is a script (e.g. a .py file also used as a resource), move it to a separate path so the resource and script files do not collide.

Example fix

# before
wmill script push assets/dataset.csv

# after
wmill resource push assets/dataset.resource.yaml
Defensive patterns

Strategy: validation

Validate before calling

if (/\.resource\.yaml$/.test(filePath) || isResourceContentFile(filePath)) {
  // route to resource push instead
  // execSync(`wmill resource push ${filePath}`);
  return;
}

Prevention

When it happens

Trigger: Running `wmill script push` on a path where isFileResource(filePath) || isFilesetResource(filePath) is true — i.e. a file resource content file (e.g. a binary/data file backing a 'file' resource) or fileset content. Detected before any API call.

Common situations: Bulk-pushing a directory containing both scripts and file-resource assets; misremembering which extension maps to scripts vs resources; trying to version a data file as a script.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/8b71cfff413e7cf7. Report an issue: GitHub.