{"record":{"id":"8288616e27b736f6","repo":"windmill-labs/windmill","slug":"failed-to-parse-code-828861","errorCode":null,"errorMessage":"Failed to parse code","messagePattern":"Failed to parse code","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-csharp/src/lib.rs","lineNumber":35,"sourceCode":"    pub class_name: Option<String>,\n    pub main_sig: MainArgSignature,\n}\n\nfn csharp_param_default_value<'a>(def: Node<'a>, code: &str) -> Option<serde_json::Value> {\n    def.utf8_text(code.as_bytes())\n        .ok()\n        .and_then(|content| serde_json::from_str(content).ok())\n}\n\npub fn parse_csharp_sig_meta(code: &str) -> anyhow::Result<CsharpMainSigMeta> {\n    let mut parser = tree_sitter::Parser::new();\n    let language = tree_sitter_c_sharp::LANGUAGE;\n    parser\n        .set_language(&language.into())\n        .map_err(|e| anyhow!(\"Error setting c# as language: {e}\"))?;\n\n    // Parse code\n    let tree = parser.parse(code, None).expect(\"Failed to parse code\");\n    let root_node = tree.root_node();\n\n    // Traverse the AST to find the Main method signature\n    let main_sig = find_main_signature(root_node, code);\n    let auto_kind = if main_sig.is_none() {\n        Some(\"lib\".to_string())\n    } else {\n        None\n    };\n    let mut is_async = false;\n    let mut is_public = false;\n    let mut returns_void = false;\n    let mut class_name = None;\n\n    let mut args = vec![];\n    if let Some((sig, name)) = main_sig {\n        class_name = name;\n        for sig_node in sig.children(&mut sig.walk()) {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-csharp/src/lib.rs#L17-L53","documentation":"parse_csharp_sig_meta parses C# source with tree-sitter to find the Main method signature and derive the script kind. parser.parse(code, None) returns a tree that is unwrapped with .expect(\"Failed to parse code\"), which panics when the tree-sitter parse produces no tree (allocation/parse failure). Despite the message wording, most malformed C# still yields a tree — this expect fires on hard parse failures, and downstream find_main_signature returns None for code without Main.","triggerScenarios":"Calling parse_csharp_signature/parse_csharp_sig_meta (script upload/analysis path for csharp scripts) where tree_sitter cannot produce a parse tree for the supplied code.","commonSituations":"Uploading a C# script with severely malformed/truncated source, non-UTF8 or binary content, or an empty payload; a tree-sitter-c-sharp grammar/runtime mismatch after dependency updates.","solutions":["Validate the C# source compiles/parses locally (dotnet build or a C# linter) before uploading.","Ensure the script content is complete, UTF-8 text and non-empty.","If parsing valid code, pin/update tree-sitter-c-sharp to a version matching the tree-sitter runtime in Cargo.lock.","In code, replace the expect with graceful error handling so malformed scripts report a user-facing validation error instead of panicking."],"exampleFix":"// before\nlet tree = parser.parse(code, None).expect(\"Failed to parse code\");\n// after\nlet tree = parser\n    .parse(code, None)\n    .ok_or_else(|| anyhow!(\"Failed to parse code\"))?;","handlingStrategy":"try-catch","validationCode":"// Validate the C# source is non-empty, UTF-8 text before calling the parser\nfn is_plausible_csharp(code: &str) -> bool {\n    !code.trim().is_empty() && code.is_char_boundary(0)\n}","typeGuard":null,"tryCatchPattern":"// The call panics via expect, so run it on an isolated thread if callers must survive:\nlet result = std::panic::catch_unwind(|| parse_csharp_sig_meta(code));\nmatch result {\n    Ok(Ok(meta)) => meta,\n    _ => return Err(anyhow!(\"C# script could not be parsed; check syntax\")),\n}","preventionTips":["Validate C# syntax (dotnet build/linter) before uploading scripts","Ensure script content is complete, non-empty UTF-8 text","Pin tree-sitter-c-sharp to a version compatible with the tree-sitter runtime"],"tags":["csharp","tree-sitter","parsing","panic"],"backgroundTag":"syntax-parse-failed","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"}