{"record":{"id":"9e529497e9fe38a4","repo":"tui-cs/Terminal.Gui","slug":"propertyname-unexpected-token-when-parsing-attr","errorCode":null,"errorMessage":"{propertyName}: Unexpected token when parsing Attribute: {reader.TokenType}.","messagePattern":"(.+?): Unexpected token when parsing Attribute: (.+?)\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Terminal.Gui/Configuration/AttributeJsonConverter.cs","lineNumber":60,"sourceCode":"            {\n                if (foreground is null || background is null)\n                {\n                    throw new JsonException ($\"{propertyName}: Both Foreground and Background colors must be provided.\");\n                }\n\n                if (style.HasValue)\n                {\n                    return new Attribute (foreground.Value, background.Value, style.Value);\n                }\n                else\n                {\n                    return new Attribute (foreground.Value, background.Value);\n                }\n            }\n\n            if (reader.TokenType != JsonTokenType.PropertyName)\n            {\n                throw new JsonException ($\"{propertyName}: Unexpected token when parsing Attribute: {reader.TokenType}.\");\n            }\n\n            propertyName = reader.GetString ()!;\n            reader.Read ();\n            string property = reader.TokenType == JsonTokenType.String\n                                  ? $\"\\\"{reader.GetString ()}\\\"\"\n                                  : $\"<{reader.TokenType}>\";\n\n            try\n            {\n                switch (propertyName?.ToLower ())\n                {\n                    case \"foreground\":\n                        foreground = JsonSerializer.Deserialize (ref reader, TuiSerializerContext.Instance.Color);\n\n                        break;\n                    case \"background\":\n                        background = JsonSerializer.Deserialize (ref reader, TuiSerializerContext.Instance.Color);","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/Configuration/AttributeJsonConverter.cs#L42-L78","documentation":"Thrown by AttributeJsonConverter.Read while deserializing an Attribute JSON object. After reading a property value, the next token must be another PropertyName (next property) or EndObject (close brace). Any other token type means the JSON is structurally malformed inside the Attribute object (e.g. a stray value, missing comma, or a value where a key belongs). The message names the last-seen propertyName for context.","triggerScenarios":"A JSON theme/config entry has a malformed Attribute object, e.g. { \"Foreground\": \"Red\", 123 } where a number appears where a property name is expected, or a trailing value without a key. Triggered via ConfigurationManager.Load/Apply of any config file that contains an Attribute (Scheme entries, etc.).","commonSituations":"Hand-edited Terminal.Gui config JSON with a typo; a config file generated by an external tool that omits a property name; copy-paste of a Scheme definition that lost a key; migrating from an older config format that used a different Attribute shape.","solutions":["Open the offending config file and locate the Attribute object named in the error; ensure every entry is a \"key\": value pair.","Validate the JSON with a linter/JSON schema before passing it to ConfigurationManager.Load.","Compare the structure to a known-good Attribute: { \"Foreground\": \"BrightRed\", \"Background\": \"Black\", \"Style\": \"Bold\" }.","If loading programmatically, set ConfigurationManager.ThrowOnJsonErrors = false to log-and-continue instead of throwing (the error moves to the JSON error list)."],"exampleFix":"// before (broken)\n{ \"Foreground\": \"Red\", \"Bold\" }\n// after (fixed)\n{ \"Foreground\": \"Red\", \"Style\": \"Bold\" }","handlingStrategy":"validation","validationCode":"// Validate the Attribute object shape before handing JSON to ConfigurationManager.\nusing var doc = JsonDocument.Parse (jsonString);\nif (doc.RootElement.ValueKind == JsonTokenType.StartObject\n    && doc.RootElement.EnumerateObject ().Any (p => p.Value.ValueKind == JsonTokenType.Number && p.Name is not (\"Style\")))\n{\n    // suspect — every Attribute value should be a string/object, not a bare number\n}\n// Strongest check: parse fully and confirm only known keys.\nforeach (var prop in doc.RootElement.EnumerateObject ())\n{\n    if (prop.Name.ToLower () is not (\"foreground\" or \"background\" or \"style\"))\n        throw new InvalidOperationException ($\"Unknown Attribute key: {prop.Name}\");\n}","typeGuard":null,"tryCatchPattern":"try { ConfigurationManager.Apply (); }\ncatch (JsonException ex) when (ex.Message.Contains (\"Unexpected token when parsing Attribute\"))\n{\n    // log ex, flag the config file for repair; do not crash the UI\n}","preventionTips":["Validate config JSON with System.Text.Json.JsonDocument.Parse before Load.","Keep a JSON schema for Terminal.Gui config and run it in CI.","Generate config by serializing a known-good Attribute, never by hand."],"tags":["configuration","json","theming","attribute"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}