elsa-workflows/elsa-core · error · InvalidOperationException
Unsupported JsonValueKind
Error message
Unsupported JsonValueKind: {element.ValueKind} What it means
JsonElementConverter maps a System.Text.Json JsonElement to a Jint JsValue, handling Object, Array, String, Number, True, False, Undefined, and Null kinds. Any other JsonValueKind (e.g. certain document-root or exotic kinds surfaced by newer parsers) has no mapping and throws this InvalidOperationException. It marks an unhandled JSON element shape in the JavaScript expression bridge.
Solutions
- Ensure the JsonElement is fully materialized (use JsonDocument.Parse(...).RootElement or Clone()) before conversion
- Check element.ValueKind before calling and normalize unsupported kinds to Object/Null
- Inspect the value's ValueKind at the failing point and fix the producer of the JSON
- Extend JsonElementConverter.ConvertJsonElementToJsValue with a mapping for the missing kind
Example fix
// before JsValue v = converter.Convert(jsonDoc.RootElement); // kind not handled // after using var doc = JsonDocument.Parse(json); var element = doc.RootElement.Clone(); // materialized Object/Array/String/Number JsValue v = converter.Convert(element);
Defensive patterns
Strategy: type-guard
Validate before calling
bool IsSupportedKind(JsonElement e) => e.ValueKind is JsonValueKind.Object or JsonValueKind.Array
or JsonValueKind.String or JsonValueKind.Number
or JsonValueKind.True or JsonValueKind.False
or JsonValueKind.Undefined or JsonValueKind.Null;
if (!IsSupportedKind(element)) throw new InvalidOperationException($"Unsupported JsonValueKind: {element.ValueKind}"); Type guard
static bool IsConvertibleToJsonValue(JsonElement element) =>
element.ValueKind is not (JsonValueKind.Object or JsonValueKind.Array or JsonValueKind.String
or JsonValueKind.Number or JsonValueKind.True or JsonValueKind.False
or JsonValueKind.Undefined or JsonValueKind.Null) is false; Try / catch
try { jsValue = converter.ConvertJsonElementToJsValue(element); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Unsupported JsonValueKind"))
{
// normalize: treat unhandled kinds as Null or re-materialize the element
jsValue = JsValue.Null;
} Prevention
- Always pass fully materialized JsonElements (RootElement from a parsed JsonDocument, or Clone())
- Check ValueKind before crossing the JSON-to-JS boundary
- Keep System.Text.Json and Jint converter code in sync with new JsonValueKind values
- Unit-test the converter against every JsonValueKind
When it happens
Trigger: Passing a JsonElement whose ValueKind is not one of the handled kinds into TryConvert during JS variable/argument conversion — typically a JsonDocument root element obtained without Read(), or a kind introduced by a newer System.Text.Json version.
Common situations: Passing JsonDocument.RootElement before calling the clone/read pattern; converting values from custom JSON readers; framework upgrades introducing kinds the converter predates; feeding non-standard JSON tokens.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot deserialize to .
- Failed to deserialize
- Invalid variable test values.
- The binding to activity type
- Input ' ' of the ' ' binding does not hold valid JSON
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/90c50377d257110b.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Expressions.JavaScript/ObjectConverters/JsonElementConverter.cs:39
return false;
}
private static JsValue ConvertJsonElementToJsValue(Engine engine, JsonElement element) =>
element.ValueKind switch
{
JsonValueKind.Object => JsValue.FromObject(engine, JsonObject.Create(element)),
JsonValueKind.Array => JsValue.FromObject(engine, JsonArray.Create(element)),
// JsString.Create is the counterpart of the JsNumber.Create and JsBoolean uses below: it produces the
// string value directly, where JsValue.FromObject would re-enter the whole conversion pipeline — the
// registered object converters, this one included, followed by the default converter's type switch —
// to arrive at the same call. It became public in Jint 4.15.3.
JsonValueKind.String => JsString.Create(element.GetString()!),
JsonValueKind.Number => element.TryGetInt32(out var intValue) ? JsNumber.Create(intValue) : JsNumber.Create(element.GetDouble()),
JsonValueKind.True => JsBoolean.True,
JsonValueKind.False => JsBoolean.False,
JsonValueKind.Undefined => JsValue.Undefined,
JsonValueKind.Null => JsValue.Null,
_ => throw new InvalidOperationException($"Unsupported JsonValueKind: {element.ValueKind}")
};
}View on GitHub (pinned to fe9217bdfa)