{"record":{"id":"41e30b541ab0b458","repo":"windmill-labs/windmill","slug":"path-is-not-a-directory-targetdirectory","errorCode":null,"errorMessage":"Path is not a directory: ${targetDirectory}","messagePattern":"Path is not a directory: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/lint/lint.ts","lineNumber":664,"sourceCode":"export async function runLint(\n  opts: LintOptions,\n  directory?: string,\n): Promise<LintReport> {\n  const initialCwd = process.cwd();\n  const explicitTargetDirectory = directory\n    ? path.resolve(initialCwd, directory)\n    : undefined;\n\n  const { json: _json, ...syncOpts } = opts;\n  const mergedOpts = await mergeConfigWithConfigFile(syncOpts);\n  const targetDirectory = explicitTargetDirectory ?? process.cwd();\n\n  const stats = await stat(targetDirectory).catch(() => null);\n  if (!stats) {\n    throw new Error(`Directory not found: ${targetDirectory}`);\n  }\n  if (!stats.isDirectory()) {\n    throw new Error(`Path is not a directory: ${targetDirectory}`);\n  }\n\n  // When the user specifies a subdirectory (that doesn't contain wmill.yaml),\n  // skip include/exclude filters since they're relative to the project root.\n  const isSubdirectory = explicitTargetDirectory &&\n    !(await stat(path.join(targetDirectory, \"wmill.yaml\")).catch(() => null));\n  const ignore = isSubdirectory\n    ? (_p: string, _isDir: boolean) => false\n    : await ignoreF(mergedOpts);\n  const root = await FSFSElement(targetDirectory, [], false);\n  const validator = new WindmillYamlValidator();\n\n  const warnings: LintWarning[] = [];\n  const issues: FileIssue[] = [];\n  let scannedFiles = 0;\n  let validatedFiles = 0;\n  let validFiles = 0;\n  let skippedUnsupportedFiles = 0;","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/lint/lint.ts#L646-L682","documentation":"Thrown by `wmill lint` (runLint) when the target path exists but is a file (or other non-directory node) rather than a directory. The lint command walks a directory of scripts/flows/apps, so a single-file target is rejected with this explicit message.","triggerScenarios":"Running `wmill lint path/to/script.ts` (a file) instead of the containing directory, or passing a glob that expanded to a file.","commonSituations":"Wanting to lint a single script but the CLI only supports directory targets; shell tab-completion picked a file; passing a config file (wmill.yaml) as the target by mistake.","solutions":["Pass the containing directory instead of the individual file, e.g. `wmill lint ./scripts`.","Lint the whole project root (where wmill.yaml lives) and filter results rather than targeting one file.","If you intended to lint a file, check whether the CLI version you run supports a file target; otherwise upgrade or use the directory scope."],"exampleFix":"// before\nwmill lint ./scripts/cleanup.ts\n\n// after\nwmill lint ./scripts","handlingStrategy":"validation","validationCode":"const st = fs.statSync(target);\nif (!st.isDirectory()) throw new Error(`${target} is a file; pass its parent directory instead`);","typeGuard":null,"tryCatchPattern":"try {\n  await runLint(opts, dir);\n} catch (e: any) {\n  if (e.message.startsWith(\"Path is not a directory\")) {\n    console.error(`${e.message} — pass the containing directory, e.g. \\`wmill lint ./scripts\\``);\n  }\n  process.exitCode = 2;\n}","preventionTips":["Remember `wmill lint` only accepts directories — never pass individual script files.","Watch for shell glob expansion turning your argument into a single file path.","Lint the project root and filter output instead of targeting single files."],"tags":["cli","filesystem","validation"],"backgroundTag":"path-is-not-a-directory","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"}