{"record":{"id":"ea744dd4e88898b3","repo":"windmill-labs/windmill","slug":"cannot-preview-a-script-metadata-file-point-to-th","errorCode":null,"errorMessage":"Cannot preview a script metadata file, point to the script content file instead (.py, .ts, .go, .sh)","messagePattern":"Cannot preview a script metadata file, point to the script content file instead \\(\\.py, \\.ts, \\.go, \\.sh\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/script/script.ts","lineNumber":1876,"sourceCode":"  filePath = toSyncRootRelativePath(filePath, cwdBeforeConfig);\n  const remotePath = scriptPathToRemotePath(filePath);\n  assertRemotePath(remotePath, argPath);\n\n  // Same as push: a descriptor-less dbt project's content path is deliberately\n  // absent, and the project beside it is what says the script is real.\n  const absentDescriptor = await stat(filePath).then(\n    () => false,\n    (e) => isMissingDbtDescriptor(filePath, e)\n  );\n  if (!absentDescriptor) {\n    const fstat = await stat(filePath);\n    if (!fstat.isFile()) {\n      throw new Error(\"file path must refer to a file.\");\n    }\n  }\n\n  if (filePath.endsWith(\".script.json\") || filePath.endsWith(\".script.yaml\")) {\n    throw Error(\n      \"Cannot preview a script metadata file, point to the script content file instead (.py, .ts, .go, .sh)\"\n    );\n  }\n\n  const codebases = await listSyncCodebases(opts);\n  const language = inferContentTypeFromFilePath(filePath, opts?.defaultTs);\n  const content = await readScriptContent(filePath);\n  const input = opts.data ? await resolve(opts.data) : {};\n\n  // Read modules from the bundle folder if present. Same suffix and same\n  // verbatim read as deploy: a dbt project lives in `__dbt/`, and parsing its\n  // files as scripts would drop the `dbt_project.yml` the executor looks for.\n  const isFolderLayout = isModuleEntryPoint(filePath);\n  const isDbt = language === \"dbt\";\n  const moduleFolderPath = isFolderLayout\n    ? path.dirname(filePath)\n    : filePath.substring(0, filePath.indexOf(\".\")) + getModuleFolderSuffix(language);\n  const modules = await readModulesFromDisk(","sourceCodeStart":1858,"sourceCodeEnd":1894,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/script/script.ts#L1858-L1894","documentation":"`wmill script` preview/analysis commands operate on script CONTENT files; passing a script metadata file (.script.json or .script.yaml) is rejected because the metadata alone does not identify the code to preview.","triggerScenarios":"Running a preview-style command (around line 1876 of script.ts) with a path ending in .script.json or .script.yaml; the check happens after confirming the path is a file.","commonSituations":"Tab-completing or pasting the metadata file path instead of the sibling content file; scripting over a directory and iterating all files including metadata.","solutions":["Point the command at the script content file: the sibling .py, .ts, .go or .sh","Strip the .script.yaml/.script.json extension to derive the content file path","Filter out *.script.json/*.script.yaml when scripting over a folder"],"exampleFix":"// before\nwmill script analyze f/scripts/my_script.script.yaml\n// after\nwmill script analyze f/scripts/my_script.py","handlingStrategy":"validation","validationCode":"if (/\\.script\\.(json|yaml)$/.test(filePath)) throw new Error(`Pass the content file instead of metadata: ${filePath.replace(/\\.script\\.(json|yaml)$/, '')}`);","typeGuard":"function isScriptMetadata(p: string): boolean { return p.endsWith('.script.json') || p.endsWith('.script.yaml'); }","tryCatchPattern":null,"preventionTips":["Strip the .script.yaml/.script.json extension to derive the content path before invoking CLI commands","Filter metadata files out when iterating folders in scripts","Remember the rule: metadata (.script.json/.script.yaml) pairs with a content file (.py/.ts/.go/.sh)"],"tags":["cli","file-path","usage"],"backgroundTag":"wrong-file-type","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"}