{"record":{"id":"15cc9c33f8520209","repo":"elsa-workflows/elsa-core","slug":"expected-an-object-of-string-metadata-values","errorCode":null,"errorMessage":"Expected an object of string metadata values.","messagePattern":"Expected an object of string metadata values\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"src/modules/Elsa.Secrets/Models/OrdinalIgnoreCaseDictionaryConverter.cs","lineNumber":14,"sourceCode":"using System.Text.Json;\nusing System.Text.Json.Serialization;\n\nnamespace Elsa.Secrets.Models;\n\npublic class OrdinalIgnoreCaseDictionaryConverter : JsonConverter<IDictionary<string, string>>\n{\n    public override IDictionary<string, string> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)\n    {\n        if (reader.TokenType == JsonTokenType.Null)\n            return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n\n        if (reader.TokenType != JsonTokenType.StartObject)\n            throw new JsonException(\"Expected an object of string metadata values.\");\n\n        var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n        while (reader.Read())\n        {\n            if (reader.TokenType == JsonTokenType.EndObject)\n                return values;\n\n            if (reader.TokenType != JsonTokenType.PropertyName)\n                throw new JsonException(\"Expected a metadata property name.\");\n\n            var key = reader.GetString()!;\n            if (!reader.Read())\n                throw new JsonException(\"Unexpected end of JSON while reading secret metadata.\");\n\n            if (reader.TokenType == JsonTokenType.Null)\n                continue;\n\n            if (reader.TokenType != JsonTokenType.String)","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/elsa-workflows/elsa-core/blob/fe9217bdfa0e27f0e09e45006eb6898f616e513d/src/modules/Elsa.Secrets/Models/OrdinalIgnoreCaseDictionaryConverter.cs#L1-L32","documentation":"OrdinalIgnoreCaseDictionaryConverter.Read deserializes the secret Metadata dictionary. If the JSON token is neither null nor a start-object, the converter throws this JsonException because metadata must be a JSON object mapping property names to string values. It indicates the stored/serialized Metadata field has an incompatible shape.","triggerScenarios":"Deserializing a Secret where the metadata field is an array, string, or number instead of an object — e.g. \"metadata\": [\"a\",\"b\"] or \"metadata\": \"env=prod\".","commonSituations":"Hand-edited stored documents; data written by an older schema or external tool; clients sending metadata as a flattened string.","solutions":["Make metadata a JSON object of string values: \"metadata\": { \"env\": \"prod\" }.","If there is no metadata, set the field to null or {}.","Migrate old documents to the current Secret schema.","Validate external JSON's metadata shape before deserialization."],"exampleFix":"// before\n{ \"metadata\": \"env=prod;team=platform\" }\n\n// after\n{ \"metadata\": { \"env\": \"prod\", \"team\": \"platform\" } }","handlingStrategy":"validation","validationCode":"using var doc = JsonDocument.Parse(json);\nif (doc.RootElement.TryGetProperty(\"metadata\", out var m) && m.ValueKind is not (JsonValueKind.Object or JsonValueKind.Null))\n    throw new JsonException(\"'metadata' must be an object of string values.\");","typeGuard":"static bool IsValidMetadataJson(JsonElement el) => el.ValueKind is JsonValueKind.Object or JsonValueKind.Null;","tryCatchPattern":"try { var secret = JsonSerializer.Deserialize<Secret>(json, options); }\ncatch (JsonException ex) when (ex.Message.Contains(\"metadata\")) { /* repair metadata field or reject payload */ }","preventionTips":["Always serialize metadata as a string-to-string JSON object.","Convert structured metadata to strings (or JSON-encoded values) at the boundary.","Share the repository's serializer options when writing documents manually."],"tags":["json","deserialization","metadata","validation"],"backgroundTag":"invalid-argument-format","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"}