elsa-workflows/elsa-core · error · JsonException
Cannot convert to bool?
Error message
Cannot convert {reader.TokenType} to bool? What it means
NullableBooleanConverter converts JSON booleans, parseable "true"/"false" strings, and JSON null into bool?. Any other token type (number, object, array, unparseable string) causes Read to throw this JsonException naming the token type.
Solutions
- Send true, false, null, or the strings "true"/"false".
- If the source emits 1/0, extend or replace the converter to map numbers to booleans.
- If the source emits "yes"/"no", pre-map the payload or use a custom converter with a lookup.
- Check the failing property name via the serializer path in the exception to fix the right field.
Example fix
// before
{"archived": 0}
// after
{"archived": false} Defensive patterns
Strategy: validation
Validate before calling
var ok = node.ValueKind is JsonValueKind.True or JsonValueKind.False or JsonValueKind.Null
|| (node.ValueKind == JsonValueKind.String && bool.TryParse(node.GetString(), out _));
if (!ok) throw new FormatException($"Expected bool?/null, got {node.ValueKind}"); Type guard
bool IsNullableJsonBool(JsonElement e) => e.ValueKind is JsonValueKind.Null or JsonValueKind.True or JsonValueKind.False || (e.ValueKind == JsonValueKind.String && bool.TryParse(e.GetString(), out _));
Try / catch
try { flag = JsonSerializer.Deserialize<bool?>(json, options); }
catch (JsonException ex) { logger.LogWarning(ex, "Skipping invalid nullable boolean"); flag = null; } Prevention
- Map numeric flags (0/1) to booleans before deserialization
- Document the accepted string forms ("true"/"false") in your API contract
- Use null only to mean 'absent', not false
When it happens
Trigger: Deserializing a bool? property from a JSON number (1), a non-boolean string ("yes"), an object, or an array; JSON null is fine and yields null.
Common situations: Numeric flag encodings from legacy APIs; localized boolean spellings; accidentally mapping an object property to a bool? field in a model.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Cannot convert to bool
- Cannot deserialize to .
- Expected a metadata property name.
- Expected a string metadata value.
- Expected a string tag.
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/d0d58260e2b27a52.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Common/Converters/NullableBooleanConverter.cs:24
public class NullableBooleanConverter : JsonConverter<bool?>
{
public override bool? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.True:
return true;
case JsonTokenType.False:
return false;
case JsonTokenType.String:
var value = reader.GetString();
if (bool.TryParse(value, out var b))
return b;
break;
case JsonTokenType.Null:
return null;
}
throw new JsonException($"Cannot convert {reader.TokenType} to bool?");
}
public override void Write(Utf8JsonWriter writer, bool? value, JsonSerializerOptions options)
{
if (value.HasValue)
writer.WriteBooleanValue(value.Value);
else
writer.WriteNullValue();
}
}View on GitHub (pinned to fe9217bdfa)