windmill-labs/windmill · error

Failed to parse code

Error message

Failed to parse code

What it means

Inside `parse_ruby_sig_meta`, `parser.parse(code, None)` returning `None` is mapped to `anyhow!("Failed to parse code")`. With a language successfully set, `parse` practically returns `None` only when no language is loaded, so this indicates a parser-configuration problem rather than syntactically invalid Ruby.

Source

Thrown at backend/parsers/windmill-parser-ruby/src/lib.rs:26

use regex::Regex;
use serde_json::Value;
use tree_sitter::Node;
use tree_sitter::Range;
use windmill_parser::json_to_typ;
use windmill_parser::Arg;
use windmill_parser::MainArgSignature;

pub fn parse_ruby_sig_meta(code: &str) -> anyhow::Result<MainArgSignature> {
    let mut parser = tree_sitter::Parser::new();
    let language = tree_sitter_ruby::LANGUAGE;
    parser
        .set_language(&language.into())
        .map_err(|e| anyhow!("Error setting Ruby as language: {e}"))?;

    // Parse code
    let tree = parser
        .parse(code, None)
        .ok_or(anyhow!("Failed to parse code"))?;
    let root_node = tree.root_node();

    root_node.clone().to_string();
    // Traverse the AST to find the Main method signature
    let args = find_main_signature(root_node, code)?;
    let auto_kind = if args.is_none() {
        Some("lib".to_string())
    } else {
        None
    };

    let main_sig = MainArgSignature {
        star_args: false,
        star_kwargs: false,
        args: args.unwrap_or_default(),
        has_preprocessor: None,
        auto_kind,
        ..Default::default()

View on GitHub (pinned to e474e8803c)

Solutions

  1. Verify `set_language(&tree_sitter_ruby::LANGUAGE.into())?` runs and propagates its error before parse
  2. Construct a fresh `Parser` per call instead of reusing one whose language may have been reset
  3. Improve the message to include why parse returned None for debuggability

Example fix

// before
.ok_or(anyhow!("Failed to parse code"))?;
// after
.ok_or_else(|| anyhow!("Failed to parse Ruby code: parser returned None (no language set?)"))?;
Defensive patterns

Strategy: validation

Validate before calling

// Validate inputs and parser setup before relying on signature extraction:
assert!(!code.trim().is_empty(), "Ruby source must be non-empty");
// ensure language loads with the same parser setup the library uses:
let mut p = tree_sitter::Parser::new();
p.set_language(&tree_sitter_ruby::LANGUAGE.into()).expect("ruby grammar");

Try / catch

match parse_ruby_sig_meta(code) {
    Ok(m) => m,
    Err(e) if e.to_string() == "Failed to parse code" => {
        // parser had no language: log infra error, do not blame user's script
        Err(anyhow!("Ruby signature parse returned no tree (infra)"))
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: Calling `parse_ruby_sig_meta` when the parser's `parse` yields `None` — i.e. no language loaded or an external cancellation triggered — during signature extraction of a Ruby script.

Common situations: Code paths that bypass `set_language`; reuse of a reset parser instance; forks where set_language failure is ignored with `let _ =`.

Understand the failure class

Related errors


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