elsa-workflows/elsa-core · error · JsonException

Expected a string tag.

Error message

Expected a string tag.

What it means

While reading the tags array, every element must be a JSON string; CaseInsensitiveHashSetConverter.Read throws this JsonException when an array element has another token type (number, object, bool, etc.). Only well-formed string tags are accepted, and blank strings are silently dropped.

Solutions

  1. Make every tags element a string: "tags": ["prod", "42"].
  2. Remove non-string elements from the array.
  3. Fix the producer (client script, migration, editor) to quote tag values.
  4. Add schema validation on ingest to reject mixed-type arrays early.

Example fix

// before
{ "tags": ["prod", 42] }

// after
{ "tags": ["prod", "42"] }
Defensive patterns

Strategy: validation

Validate before calling

using var doc = JsonDocument.Parse(json);
var tags = doc.RootElement;
if (tags.ValueKind == JsonValueKind.Array && tags.EnumerateArray().Any(e => e.ValueKind != JsonValueKind.String))
    throw new JsonException("All tag elements must be strings.");

Type guard

static bool AllTagsAreStrings(JsonElement el) => el.ValueKind != JsonValueKind.Array || el.EnumerateArray().All(e => e.ValueKind == JsonValueKind.String);

Try / catch

try { var secret = JsonSerializer.Deserialize<Secret>(json, options); }
catch (JsonException ex) when (ex.Message.Contains("string tag")) { /* sanitize tags array and retry */ }

Prevention

When it happens

Trigger: Deserializing a tags array containing non-string elements, e.g. "tags": ["prod", 42] or [null, {"k":1}].

Common situations: Externally generated JSON with mixed-type arrays; hand-edited stored documents; a client/tool writing tags as numbers or objects.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/24646096f20b3952. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.Secrets/Models/CaseInsensitiveHashSetConverter.cs:23

public class CaseInsensitiveHashSetConverter : JsonConverter<HashSet<string>>
{
    public override HashSet<string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Null)
            return new HashSet<string>(StringComparer.OrdinalIgnoreCase);

        if (reader.TokenType != JsonTokenType.StartArray)
            throw new JsonException("Expected an array of strings.");

        var values = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndArray)
                return values;

            if (reader.TokenType != JsonTokenType.String)
                throw new JsonException("Expected a string tag.");

            var value = reader.GetString();
            if (!string.IsNullOrWhiteSpace(value))
                values.Add(value);
        }

        throw new JsonException("Unexpected end of JSON while reading secret tags.");
    }

    public override void Write(Utf8JsonWriter writer, HashSet<string> value, JsonSerializerOptions options)
    {
        writer.WriteStartArray();
        foreach (var item in value.Order(StringComparer.OrdinalIgnoreCase))
            writer.WriteStringValue(item);
        writer.WriteEndArray();
    }
}

View on GitHub (pinned to fe9217bdfa)