{"record":{"id":"0af079f67ad033a2","repo":"windmill-labs/windmill","slug":"error-parsing-code-0af079","errorCode":null,"errorMessage":"Error parsing code: {}","messagePattern":"Error parsing code: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-py/src/lib.rs","lineNumber":314,"sourceCode":"\n/// skip_params is a micro optimization for when we just want to find the main\n/// function without parsing all the params.\npub fn parse_python_signature(\n    code: &str,\n    override_main: Option<String>,\n    skip_params: bool,\n) -> anyhow::Result<MainArgSignature> {\n    let main_name = override_main.unwrap_or(\"main\".to_string());\n\n    let has_preprocessor = !filter_non_main(code, \"preprocessor\").is_empty();\n\n    // Optimization: Parse code only once\n    // - If models detected: parse full code, extract main from it, keep AST for type detection\n    // - If no models: parse only the filtered main function\n    let (params, module) = if should_parse_for_models(code) {\n        // Parse full code once for both Pydantic detection and signature extraction\n        let ast = Suite::parse(code, \"main.py\")\n            .map_err(|e| anyhow::anyhow!(\"Error parsing code: {}\", e.to_string()))?;\n\n        // Extract main function from full AST\n        let params = ast.iter().find_map(|x| match x {\n            Stmt::FunctionDef(StmtFunctionDef { name, args, .. }) if name == &main_name => {\n                Some(args.as_ref().clone())\n            }\n            Stmt::AsyncFunctionDef(StmtAsyncFunctionDef { name, args, .. })\n                if name == &main_name =>\n            {\n                Some(args.as_ref().clone())\n            }\n            _ => None,\n        });\n\n        // Keep AST for Pydantic/dataclass detection\n        (params, Some(ast))\n    } else {\n        // No models detected - parse only the filtered main function","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-py/src/lib.rs#L296-L332","documentation":"parse_python_signature in windmill-parser-py first checks should_parse_for_models(code); when Pydantic-style models are detected it parses the FULL file with ruff's Suite::parse to both detect models and extract the main function's arguments. A syntax error anywhere in the file surfaces as 'Error parsing code: ...' from this line.","triggerScenarios":"Calling parse_python_signature on a script that contains model definitions (so the full-file parse path is taken) and has a syntax error anywhere in the file — including code far from the main function that the filtered path would have skipped.","commonSituations":"Pydantic/dataclass-based scripts with an unrelated syntax error in helper functions, Python-version-mismatched syntax, or template placeholders left in generated model files.","solutions":["Read the wrapped message for the exact line/column and fix the syntax error in the file.","Validate with 'python -m py_compile main.py' before deploying.","Remove template placeholders, smart quotes, or truncated blocks.","Note the full-file parse is triggered by model definitions: even fixing only near 'def main' is not enough — the whole file must be valid Python.","Confirm the syntax features used match the Python version the parser targets."],"exampleFix":"// before\nclass Item(BaseModel):\n    name: str\n    price int\n\n// after\nclass Item(BaseModel):\n    name: str\n    price: int","handlingStrategy":"validation","validationCode":"import ast\ndef validate_full_python(code: str) -> None:\n    # model-detection forces a FULL-file parse, so validate the entire file\n    try:\n        ast.parse(code)\n    except SyntaxError as e:\n        raise SystemExit(f'line {e.lineno}: {e.msg}')","typeGuard":null,"tryCatchPattern":"try:\n    sig = parse_python_signature(code)\nexcept Exception as e:\n    if 'Error parsing code:' in str(e):\n        raise RuntimeError(f'Fix Python syntax (whole file is parsed when models are present): {e}') from e\n    raise","preventionTips":["Remember: scripts with Pydantic/dataclass models parse the WHOLE file — all of it must be valid","Run py_compile/ruff check before deploying any script","Fix the exact line/column from the wrapped error message","Keep generated model files free of template placeholders"],"tags":["python","parser","syntax-error","pydantic"],"backgroundTag":"syntax-error","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"}