{"record":{"id":"24646096f20b3952","repo":"elsa-workflows/elsa-core","slug":"expected-a-string-tag","errorCode":null,"errorMessage":"Expected a string tag.","messagePattern":"Expected a string tag\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Secrets/Models/CaseInsensitiveHashSetConverter.cs","lineNumber":23,"sourceCode":"\npublic class CaseInsensitiveHashSetConverter : JsonConverter<HashSet<string>>\n{\n    public override HashSet<string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType == JsonTokenType.Null)\n            return new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n\n        if (reader.TokenType != JsonTokenType.StartArray)\n            throw new JsonException(\"Expected an array of strings.\");\n\n        var values = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n        while (reader.Read())\n        {\n            if (reader.TokenType == JsonTokenType.EndArray)\n                return values;\n\n            if (reader.TokenType != JsonTokenType.String)\n                throw new JsonException(\"Expected a string tag.\");\n\n            var value = reader.GetString();\n            if (!string.IsNullOrWhiteSpace(value))\n                values.Add(value);\n        }\n\n        throw new JsonException(\"Unexpected end of JSON while reading secret tags.\");\n    }\n\n    public override void Write(Utf8JsonWriter writer, HashSet<string> value, JsonSerializerOptions options)\n    {\n        writer.WriteStartArray();\n        foreach (var item in value.Order(StringComparer.OrdinalIgnoreCase))\n            writer.WriteStringValue(item);\n        writer.WriteEndArray();\n    }\n}\n","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Secrets/Models/CaseInsensitiveHashSetConverter.cs#L5-L41","documentation":"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.","triggerScenarios":"Deserializing a tags array containing non-string elements, e.g. \"tags\": [\"prod\", 42] or [null, {\"k\":1}].","commonSituations":"Externally generated JSON with mixed-type arrays; hand-edited stored documents; a client/tool writing tags as numbers or objects.","solutions":["Make every tags element a string: \"tags\": [\"prod\", \"42\"].","Remove non-string elements from the array.","Fix the producer (client script, migration, editor) to quote tag values.","Add schema validation on ingest to reject mixed-type arrays early."],"exampleFix":"// before\n{ \"tags\": [\"prod\", 42] }\n\n// after\n{ \"tags\": [\"prod\", \"42\"] }","handlingStrategy":"validation","validationCode":"using var doc = JsonDocument.Parse(json);\nvar tags = doc.RootElement;\nif (tags.ValueKind == JsonValueKind.Array && tags.EnumerateArray().Any(e => e.ValueKind != JsonValueKind.String))\n    throw new JsonException(\"All tag elements must be strings.\");","typeGuard":"static bool AllTagsAreStrings(JsonElement el) => el.ValueKind != JsonValueKind.Array || el.EnumerateArray().All(e => e.ValueKind == JsonValueKind.String);","tryCatchPattern":"try { var secret = JsonSerializer.Deserialize<Secret>(json, options); }\ncatch (JsonException ex) when (ex.Message.Contains(\"string tag\")) { /* sanitize tags array and retry */ }","preventionTips":["Quote tag values in any JSON you generate for secrets.","Run schema validation before deserializing external payloads.","Normalize tags (ToString + trim) at the boundary before serialization."],"tags":["json","deserialization","tags","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"fe9217bdfa0e27f0e09e45006eb6898f616e513d","analyzedAt":"2026-09-13T20:32:34.702Z","contentChangedAt":"2026-09-13T20:32:34.702Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}