{"record":{"id":"cf3bbb2984864477","repo":"windmill-labs/windmill","slug":"file-path-must-refer-to-a-file-cf3bbb","errorCode":null,"errorMessage":"file path must refer to a file.","messagePattern":"file path must refer to a file\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/schedule/schedule.ts","lineNumber":311,"sourceCode":"    workspace: workspace.workspaceId,\n    path,\n    requestBody: { enabled: false },\n  });\n\n  log.info(colors.yellow(`Schedule ${path} disabled.`));\n}\n\nasync function push(opts: GlobalOptions, filePath: string, remotePath: string) {\n  const workspace = await resolveWorkspace(opts);\n  await requireLogin(opts);\n\n  if (!validatePath(remotePath)) {\n    return;\n  }\n\n  const fstat = await stat(filePath);\n  if (!fstat.isFile()) {\n    throw new Error(\"file path must refer to a file.\");\n  }\n\n  console.log(colors.bold.yellow(\"Pushing schedule...\"));\n\n  await pushSchedule(\n    workspace.workspaceId,\n    remotePath,\n    undefined,\n    parseFromFile(filePath)\n  );\n  console.log(colors.bold.underline.green(\"Schedule pushed\"));\n}\n\nconst command = new Command()\n  .description(\"schedule related commands\")\n  .option(\"--json\", \"Output as JSON (for piping to jq)\")\n  .action(list as any)\n  .command(\"list\", \"list all schedules\")","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/schedule/schedule.ts#L293-L329","documentation":"Thrown by the Windmill CLI's `schedule push` command when the local argument does not point to a regular file. It stats filePath and requires isFile(); passing a directory (or another non-regular file) aborts the push with this error instead of attempting to read a schedule definition from it.","triggerScenarios":"Running `wmill schedule push <localPath>` where localPath is a directory such as the folder containing many `.schedule.yaml` files (the command does not recurse or batch), or a symlink to a directory. A nonexistent path fails earlier in stat with ENOENT.","commonSituations":"Trying to push a whole folder of schedules with one command; shell tab-completion selecting the directory; scripts interpolating a directory variable; confusing `schedule push` (single file) with a bulk sync command.","solutions":["Pass the specific `.schedule.yaml` file: `wmill schedule push ./schedules/nightly.schedule.yaml`","Loop over files to push a directory's worth: `for f in ./schedules/*.schedule.yaml; do wmill schedule push \"$f\"; done`","Verify the argument resolves to a regular file (`test -f`) in scripts before invoking push"],"exampleFix":"// before\nwmill schedule push ./schedules/\n// after\nwmill schedule push ./schedules/nightly.schedule.yaml\n// or bulk:\nfor f in ./schedules/*.schedule.yaml; do wmill schedule push \"$f\"; done","handlingStrategy":"validation","validationCode":"import { statSync } from 'fs';\n\nconst st = statSync(localPath);\nif (!st.isFile()) {\n  throw new Error(`schedule push expects a .schedule.yaml file, got: ${localPath}`);\n}","typeGuard":"import { statSync } from 'fs';\n\nfunction isFile(p: string): boolean {\n  try { return statSync(p).isFile(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await wmill.schedule.push(localPath);\n} catch (e) {\n  if ((e as Error).message === 'file path must refer to a file.') {\n    console.error(`${localPath} is a directory; push individual .schedule.yaml files (loop over a glob for bulk)`);\n  } else throw e;\n}","preventionTips":["Always pass a single `.schedule.yaml` file — `schedule push` does not accept directories","Use a shell loop (`for f in dir/*.schedule.yaml`) for bulk pushes","Guard scripts with `test -f \"$path\"` before calling push","Watch shell tab-completion so it does not silently select the directory"],"tags":["cli","windmill","filesystem","argument-validation"],"backgroundTag":"path-is-not-a-file","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}