{"record":{"id":"53ace9ca3bf2b6b0","repo":"windmill-labs/windmill","slug":"no-local-file-for-scriptpath-to-infer-its-s3obj","errorCode":null,"errorMessage":"No local file for ${scriptPath} to infer its S3Object parameter.","messagePattern":"No local file for (.+?) to infer its S3Object parameter\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/pipeline/pipeline.ts","lineNumber":480,"sourceCode":"// Resolve one `--upload` binding to the run-arg it injects: pick the target\n// S3Object parameter (explicit `:param`, else the script's sole S3Object arg)\n// and turn the source into an object key — an `s3://` source is used as-is, a\n// local path is uploaded to the workspace store under a deterministic dev key.\nasync function resolveUploadArgs(\n  bindings: UploadBinding[],\n  scriptPath: string,\n  workspaceId: string,\n  local: boolean | undefined,\n  localScripts: Map<string, LocalScript> | undefined,\n): Promise<Record<string, any>> {\n  // Fetch the schema at most once, and only when a binding omits `:param`.\n  let schema: any | undefined;\n  const loadSchema = async (): Promise<any> => {\n    if (schema) return schema;\n    if (local) {\n      const ls = localScripts?.get(scriptPath);\n      if (!ls) {\n        throw new Error(`No local file for ${scriptPath} to infer its S3Object parameter.`);\n      }\n      schema = (await inferSchema(ls.language as any, ls.content, {}, scriptPath)).schema;\n    } else {\n      schema = (await wmill.getScriptByPath({ workspace: workspaceId, path: scriptPath })).schema;\n    }\n    return schema;\n  };\n\n  const args: Record<string, any> = {};\n  for (const binding of bindings) {\n    let param = binding.param;\n    if (!param) {\n      const params = s3ObjectParams(await loadSchema());\n      if (params.length === 1) param = params[0];\n      else if (params.length === 0) {\n        throw new Error(`${scriptPath} declares no S3Object parameter to bind --upload to.`);\n      } else {\n        throw new Error(","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/pipeline/pipeline.ts#L462-L498","documentation":"Thrown by loadSchema in the `wmill pipeline run --upload` path when the entrypoint script is expected to be present among locally pulled scripts but is not found in the localScripts map. With --local, the CLI infers the script's parameter schema from the local file content to find an S3Object parameter; without the local file it cannot proceed.","triggerScenarios":"Running `wmill pipeline run --local --upload <tok>:<param>=<source>` where the referenced script path has no corresponding entry in the local pull state — e.g. the script was deleted or renamed locally, the path token doesn't match any pulled script, or --local was passed in a directory that was never pulled.","commonSituations":"Editing a pulled pipeline and renaming the entrypoint file without re-pulling; running from the wrong directory (no .windmill/pull state); workspace switch so local state belongs to another workspace; a stale pull where the server-side script is newer.","solutions":["Run `wmill pipeline pull` in the project root to refresh local script state, then retry.","Verify the script path/token in --upload matches an existing local file under the pulled layout.","Drop --local to resolve the schema from the deployed script on the server instead of local files.","Check you are in the directory that was pulled (wmill.yaml present) and the same workspace."],"exampleFix":"// before: stale local state\nwmill pipeline run f/pipeline --local --upload s:file=./data.csv\n\n// after\nwmill pipeline pull\nwmill pipeline run f/pipeline --local --upload s:file=./data.csv","handlingStrategy":"validation","validationCode":"if (local && !localScripts.has(scriptPath)) {\n  throw new Error(`Run \\`wmill pipeline pull\\` first — ${scriptPath} is not in local state`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await params({ local: true, /* ... */ });\n} catch (e: any) {\n  if (e.message.includes(\"No local file for\")) {\n    console.error(`${e.message} — re-pull with \\`wmill pipeline pull\\` or drop --local`);\n  }\n  throw e;\n}","preventionTips":["Always `wmill pipeline pull` in the project root before using --local flags.","Keep script paths/tokens in --upload in sync with the pulled file layout.","Don't rename local script files independently of the workspace; re-pull after server-side changes.","Verify the active workspace matches the one the pull came from."],"tags":["cli","state","validation"],"backgroundTag":"missing-local-state","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"}