elsa-workflows/elsa-core · error · JsonException
Expected a PropertyName token
Error message
Expected a PropertyName token
What it means
While iterating the JSON object, HttpHeadersConverter expects each member to be a property name (a header key). If it encounters a token other than EndObject or PropertyName at the member position, it throws JsonException('Expected a PropertyName token'), guarding against structurally invalid header objects.
Solutions
- Repair the JSON so it is a well-formed object of key->string-or-string[] pairs
- Re-serialize the headers through HttpHeaders itself instead of hand-writing JSON
- Validate with JsonDocument.Parse before deserializing into HttpHeaders
- If state is persisted, isolate and delete/repair the corrupt instance state record
Example fix
// before
{"Accept"} // invalid: missing value, breaks at member position
// after
{"Accept": ["text/plain"]} Defensive patterns
Strategy: type-guard
Validate before calling
using var doc = JsonDocument.Parse(json);
foreach (var prop in doc.RootElement.EnumerateObject())
if (prop.Value.ValueKind is not (JsonValueKind.String or JsonValueKind.Array))
throw new FormatException($"Header '{prop.Name}' has invalid value kind {prop.Value.ValueKind}"); Type guard
bool IsValidHeadersObject(JsonElement e) => e.ValueKind == JsonValueKind.Object && e.EnumerateObject().All(p => p.Value.ValueKind is JsonValueKind.String or JsonValueKind.Array);
Try / catch
try { headers = JsonSerializer.Deserialize<HttpHeaders>(json, options); }
catch (JsonException ex)
{
logger.LogWarning(ex, "Headers JSON is not a valid key/value object");
throw new InvalidDataException("Invalid HttpHeaders payload", ex);
} Prevention
- Never hand-write headers JSON; round-trip through HttpHeaders
- Sanitize persisted workflow state after serializer upgrades
- Include the deserializing type in persisted-state corruption alerts
When it happens
Trigger: Deserializing HttpHeaders from malformed JSON such as a nested array element or a bare value inside the object where a key should be, e.g. {"Accept"} or nested objects without keys — typically corrupt or hand-crafted persisted state.
Common situations: Corrupted workflow instance state in a durable store; custom code writing headers with the wrong serializer; JSON produced by another language/library that doesn't map header objects cleanly.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Expected StartObject token
- Expected a String or StartArray token
- The serialization type alias is missing.
- Unsupported console stream value
- The persisted external authentication value could not be…
AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13).
Data as JSON: /api/errors/e7f6823138af5760.
Report an issue: GitHub.
Appendix: source
Thrown at src/modules/Elsa.Http/Serialization/HttpHeadersConverter.cs:25
/// A custom JSON converter for HttpHeaders that supports both single and multiple values.
/// </summary>
public class HttpHeadersConverter : JsonConverter<HttpHeaders>
{
/// <inheritdoc />
public override HttpHeaders Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException("Expected StartObject token");
var headers = new HttpHeaders();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
return headers;
if (reader.TokenType != JsonTokenType.PropertyName)
throw new JsonException("Expected a PropertyName token");
var key = reader.GetString()!;
reader.Read();
// If the next token is not a StartArray token, then we expect a String token.
switch (reader.TokenType)
{
case JsonTokenType.StartArray:
{
var values = new List<string>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) values.Add(reader.GetString()!);
headers.Add(key, values.ToArray());
break;
}
case JsonTokenType.String:
{
var singleValue = reader.GetString()!;
headers.Add(key, new[] { singleValue });View on GitHub (pinned to fe9217bdfa)