windmill-labs/windmill · error
Unknown type `{s}`
Error message
Unknown type `{s}` What it means
find_typ maps C# type AST nodes to Windmill parameter types. When the node is an identifier whose text matches none of the whitelisted primitive/BCL types (int, string, char, float, double, bool, decimal, object and their System.* equivalents), it rejects it with this error. Windmill only supports a fixed set of C# types for main-function signatures; any custom or unrecognized type name is refused.
Source
Thrown at backend/parsers/windmill-parser-csharp/src/lib.rs:121
match typ_node.kind() {
"predefined_type" => {
match typ_node.utf8_text(code.as_bytes()) {
Ok("string") => Ok(Typ::Str(None)),
Ok("sbyte") | Ok("System.SByte") => Ok(Typ::Bytes),
Ok("byte") | Ok("System.Byte") => Ok(Typ::Bytes),
Ok("short") | Ok("System.Int16") => Ok(Typ::Int),
Ok("ushort") | Ok("System.UInt16") => Ok(Typ::Int),
Ok("int") | Ok("System.Int32") => Ok(Typ::Int),
Ok("uint") | Ok("System.UInt32") => Ok(Typ::Int),
Ok("long") | Ok("System.Int64") => Ok(Typ::Int),
Ok("ulong") | Ok("System.UInt64") => Ok(Typ::Int),
Ok("char") | Ok("System.Char") => Ok(Typ::Str(None)),
Ok("float") | Ok("System.Single") => Ok(Typ::Float),
Ok("double") | Ok("System.Double") => Ok(Typ::Float),
Ok("bool") | Ok("System.Boolean") => Ok(Typ::Bool),
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)?)
}View on GitHub (pinned to e474e8803c)
Solutions
- Change the main-signature parameter to a supported type: int, string, char, float, double, bool, decimal, object, or an array/list of those
- For custom types, accept `object` in the signature and deserialize inside the script body
- If the type is a common alias (uint, long, ulong, short, byte), extend the match arms in find_typ to map it to an existing Typ
- File an issue upstream if you believe the type should be supported
Example fix
// before static void Main(long count) // after static void Main(int count)
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check main-signature parameter types against the supported set before deploying
const SUPPORTED: &[&str] = &["int","string","char","float","double","bool","decimal","object","System.Int32","System.String","System.Char","System.Single","System.Double","System.Boolean","System.Decimal"];
fn unsupported_types(main_params: &[&str]) -> Vec<&str> {
main_params.iter().filter(|t| !SUPPORTED.contains(t)).cloned().collect()
} Type guard
fn is_supported_cs_type(t: &str) -> bool {
matches!(t, "int" | "string" | "char" | "float" | "double" | "bool" | "decimal" | "object"
| "System.Int32" | "System.String" | "System.Char" | "System.Single"
| "System.Double" | "System.Boolean" | "System.Decimal")
} Try / catch
match parse_csharp_signature(code) {
Ok(sig) => sig,
Err(e) if e.to_string().starts_with("Unknown type") => {
// degrade gracefully: fall back to a default signature instead of failing deploy
Ok(MainArgSignature::default())
}
Err(e) => Err(e),
} Prevention
- Restrict Windmill C# main parameters to the whitelisted primitive/BCL types
- Use `object` for anything richer and parse/deserialize inside the script body
- Expand numeric aliases (use int, not uint/long/short) before writing the signature
- Test signature extraction locally with parse_csharp_signature before deploying
When it happens
Trigger: A C# script whose `static void Main(...)` declares a parameter with a type that is not in the whitelist: custom classes, enums, structs, type aliases like `uint`, `long`, `short`, `byte`, `Int64`, `DateTime`, `Guid`, etc.
Common situations: Writing a Windmill C# script with `long count`, `uint id`, `DateTime start`, `Guid orderId`, `MyEnum status`; copy-pasting normal C# code into Windmill without adapting signature types to the supported set.
Related errors
- Aborted from C
- Unknown type `{s}`
- Failed to find inner type of array type
- Failed to find inner type of nullable_type
- Unexpected C# type node kind: {} for '{}'. This type is not
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/81a786b21353f192.
Report an issue: GitHub.