windmill-labs/windmill · error

Error parsing code for imports: {}

Error message

Error parsing code for imports: {}

What it means

parse_code_for_imports in windmill-parser-py-imports parses the code (with a fake 'def main(): pass' appended so the module still parses after the real main was split off) using ruff's Suite::parse. If that parse fails, the error is rethrown as 'Error parsing code for imports: ...'.

Source

Thrown at backend/parsers/windmill-parser-py-imports/src/lib.rs:190

        .lines()
        .last()
        .map(|x| x.starts_with("@"))
        .unwrap_or(false)
    {
        code = code
            .lines()
            .take(code.lines().count() - 1)
            .collect::<Vec<&str>>()
            .join("\n")
            + "\n";
    }

    // Add a fake main function to ensure the parser can process the code correctly
    // This is needed because we've split off the real main function above
    let code_with_fake_main = format!("{}\n\ndef main(): pass", code);

    let ast = Suite::parse(&code_with_fake_main, "main.py").map_err(|e| {
        anyhow::anyhow!("Error parsing code for imports: {}", e.to_string())
    })?;
    // Note: We're still using the original code for finding pins,
    // as the TextRange values from the parsed AST would be based on code_with_fake_main
    // but we want to match against the original code
    let find_pin = |range: TextRange, key: String| {
        let hs = code
            .chars()
            .skip(range.end().to_usize())
            .take_while(|e| *e != '\n')
            .collect::<String>();

        if hs.trim_start().is_empty() {
            return None;
        }

        PIN_RE.captures(&hs).and_then(|x| {
            x.get(1).zip(x.get(2)).and_then(|(ty_m, pkg_m)| {
                let pkg = pkg_m.as_str().to_owned();

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the wrapped message after 'Error parsing code for imports:' for the exact offending line/column and fix it in the original file.
  2. Run 'python -m py_compile' on the source to confirm it is valid standalone Python.
  3. Ensure the code passed in is the complete module body (not a fragment whose enclosing block was cut off).
  4. Check encoding: re-save the file as UTF-8 without BOM and normalize line endings.

Example fix

// before (fragment passed to the import parser)
    return x + 1

// after (complete module passed)
def add(x):
    return x + 1
Defensive patterns

Strategy: validation

Validate before calling

import ast
def validate_code_for_imports(code: str) -> None:
    # parse the same augmented form the parser builds (code + fake main)
    try:
        ast.parse(code + '\n\ndef main(): pass')
    except SyntaxError as e:
        raise SystemExit(f'Code invalid for import analysis, line {e.lineno}: {e.msg}')

Try / catch

try:
    imports = parse_python_imports(code)
except Exception as e:
    if 'Error parsing code for imports:' in str(e):
        raise RuntimeError(f'Fix module syntax: {e}') from e
    raise

Prevention

When it happens

Trigger: Calling parse_code_for_imports (directly or via parse_relative_imports / parse_python_imports) on Python code that is syntactically invalid — the appended fake main does not fix broken module-level syntax such as unbalanced brackets, bad indentation, or stray tokens.

Common situations: Analyzing partially-written scripts, code stored with wrong encoding producing mojibake, snippets extracted from larger files losing their enclosing block, or files with Windows/mac mixed line endings confusing indentation-sensitive parsing.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/ae444a7a23a96fca. Report an issue: GitHub.