{"record":{"id":"4964de3e1089588d","repo":"windmill-labs/windmill","slug":"cannot-find-main-function","errorCode":null,"errorMessage":"Cannot find main function.","messagePattern":"Cannot find main function\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-nu/src/lib.rs","lineNumber":35,"sourceCode":"        Args(String),\n    }\n    let mut last_token = LastToken::None;\n    for token in tokens {\n        let s = token.span;\n        let cont = src.get(s.start..s.end).ok_or(anyhow!(\"Parsing error\"))?;\n        last_token = match last_token {\n            LastToken::None if cont == \"def\" => LastToken::Def,\n            LastToken::Def if cont == \"main\" => LastToken::Main,\n            LastToken::Main => {\n                LastToken::Args(cont.get(1..(cont.len() - 1)).unwrap_or(\"Error\").to_owned())\n            }\n            LastToken::Args(_) => break,\n            _ => LastToken::None,\n        };\n    }\n\n    let LastToken::Args(args) = last_token else {\n        bail!(\"Cannot find main function.\");\n    };\n\n    let mut sig = MainArgSignature::default();\n    sig.auto_kind = None;\n\n    let batches = args\n        .lines()\n        .filter_map(|el| {\n            if el.trim_start().starts_with('#') {\n                None\n            } else {\n                Some(\n                    el.split(',')\n                        .map(|el| el.trim())\n                        .filter(|el| el != &\"\")\n                        .collect::<Vec<&str>>(),\n                )\n            }","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-nu/src/lib.rs#L17-L53","documentation":"parse_nu_signature lexes the Nushell source looking for the token sequence `def` `main` `[`...args...`]` to extract the entrypoint's parameter list. If the tokens never produce an Args state (no `def main` found, or a malformed definition), it bails. Windmill requires Nushell scripts to expose a `def main` entrypoint to infer the argument signature.","triggerScenarios":"Deploying a Nushell script that lacks `def main []` or `def main [...]`, defines main under a different name (`def run`), or has lexing quirks (e.g. `def` and `main` split by comments/odd spacing that reset the token state machine).","commonSituations":"Scripts written as plain command files with top-level statements and no main wrapper; renaming main to something custom; scripts where a comment or string between `def` and `main` resets the LastToken state.","solutions":["Add a `def main [ ... ] { ... }` entrypoint and move your logic/parameters into it.","Keep the exact lowercase `def main` on adjacent tokens — no intervening code or unusual spacing between `def` and `main`.","Name other helper functions something other than `main`, and make sure the entrypoint is literally `main`.","Verify the parameter list is enclosed in square brackets `[]` right after `main`."],"exampleFix":"// before\nprint \"hello\"\n// after\ndef main [name: string] {\n  print $\"hello ($name)\"\n}","handlingStrategy":"validation","validationCode":"function validateNuEntry(code) {\n  if (!/^\\s*def\\s+main\\s*\\[/m.test(code)) {\n    return 'Nushell scripts must define an entrypoint: def main [ ... ] { ... }';\n  }\n  return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const sig = parseNuSignature(source);\n} catch (e) {\n  if (String(e).includes('Cannot find main function')) {\n    throw new Error('Add a `def main [args] { ... }` entrypoint; Windmill cannot infer the signature without it');\n  }\n  throw e;\n}","preventionTips":["Always wrap script logic in `def main [...]` — never rely on top-level statements","Keep `def` and `main` adjacent with plain spacing, no comments/strings between them","Name helper functions anything other than `main`"],"tags":["nushell","parser","missing-entrypoint"],"backgroundTag":"missing-main-function","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"}