windmill-labs/windmill · error

Failed to find inner type of nullable_type

Error message

Failed to find inner type of nullable_type

What it means

For `nullable_type` nodes (C# `T?`), find_typ recursively resolves the inner type via child_by_field_name("type"). If the inner type child is absent from the AST, it errors with this message. Like 803, it signals the parse tree did not have the expected structure for a nullable type.

Source

Thrown at backend/parsers/windmill-parser-csharp/src/lib.rs:137

                Ok("decimal") | Ok("System.Decimal") => Ok(Typ::Float),
                Ok("object") => Ok(Typ::Object(ObjectType::new(None, Some(vec![])))), // TODO: Complete the object type
                Ok(s) => Err(anyhow!("Unknown type `{s}`")),
                Err(e) => Err(anyhow!("Error getting type name: {}", e)),
            }
        }
        "array_type" => {
            let new_typ_node = typ_node
                .child_by_field_name("type")
                .ok_or(anyhow!("Failed to find inner type of array type"))?;
            Ok(Typ::List(Box::new(find_typ(new_typ_node, code)?)))
        }
        "identifier" => Ok(Typ::Unknown),
        "generic_name" => Ok(Typ::Unknown),
        "pointer_type" => Ok(Typ::Int),
        "nullable_type" => {
            let new_typ_node = typ_node
                .child_by_field_name("type")
                .ok_or(anyhow!("Failed to find inner type of nullable_type"))?;
            Ok(find_typ(new_typ_node, code)?)
        }
        wc => Err(anyhow!(
            "Unexpected C# type node kind: {} for '{}'. This type is not handeled by Windmill, please open an issue if this seems to be an error",
            wc,
            typ_node.utf8_text(code.as_bytes())?
        )),
    }
}

fn parse_csharp_typ<'a>(
    param_node: Node<'a>,
    code: &str,
) -> anyhow::Result<(Option<String>, Typ, String)> {
    let name = param_node
        .child_by_field_name("name")
        .and_then(|n| n.utf8_text(code.as_bytes()).ok())
        .unwrap_or("");

View on GitHub (pinned to e474e8803c)

Solutions

  1. Rewrite the parameter as a plain (non-nullable) supported type, e.g. `static void Main(int? x)` becomes `static void Main(int x)`
  2. Check tree-sitter-c-sharp version alignment and rebuild with a pinned compatible version
  3. If nullability is required, model it via a default value or object parameter instead

Example fix

// before
static void Main(int? maybeCount)
// after
static void Main(int count)
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: avoid `T?` in Windmill main signatures; rewrite before deploying
if main_signature_text.contains('?') {
    // replace nullable params with plain types or default values before extraction
}

Try / catch

match parse_csharp_sig_meta(code) {
    Ok(m) => m,
    Err(e) if e.to_string().contains("nullable_type") => {
        bail!("nullable parameter in Main signature not supported — use a plain type or default value")
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: parse_csharp_sig_meta on a signature with `T?` parameters where the grammar produces a nullable_type node without the `type` field — e.g. `Main(int?)` parsed oddly, or a mismatched tree-sitter-c-sharp version.

Common situations: Scripts using nullable value types (`int?`, `bool?`, `DateTime?`) in nonstandard positions; tree-sitter grammar version drift changing nullable_type node shape; truncated source ending in `int?`.

Related errors


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