tui-cs/Terminal.Gui · error · JsonException

{propertyName}: Unexpected token when parsing Attribute: {re

Error message

{propertyName}: Unexpected token when parsing Attribute: {reader.TokenType}.

What it means

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.

Source

Thrown at Terminal.Gui/Configuration/AttributeJsonConverter.cs:60

            {
                if (foreground is null || background is null)
                {
                    throw new JsonException ($"{propertyName}: Both Foreground and Background colors must be provided.");
                }

                if (style.HasValue)
                {
                    return new Attribute (foreground.Value, background.Value, style.Value);
                }
                else
                {
                    return new Attribute (foreground.Value, background.Value);
                }
            }

            if (reader.TokenType != JsonTokenType.PropertyName)
            {
                throw new JsonException ($"{propertyName}: Unexpected token when parsing Attribute: {reader.TokenType}.");
            }

            propertyName = reader.GetString ()!;
            reader.Read ();
            string property = reader.TokenType == JsonTokenType.String
                                  ? $"\"{reader.GetString ()}\""
                                  : $"<{reader.TokenType}>";

            try
            {
                switch (propertyName?.ToLower ())
                {
                    case "foreground":
                        foreground = JsonSerializer.Deserialize (ref reader, TuiSerializerContext.Instance.Color);

                        break;
                    case "background":
                        background = JsonSerializer.Deserialize (ref reader, TuiSerializerContext.Instance.Color);

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Open the offending config file and locate the Attribute object named in the error; ensure every entry is a "key": value pair.
  2. Validate the JSON with a linter/JSON schema before passing it to ConfigurationManager.Load.
  3. Compare the structure to a known-good Attribute: { "Foreground": "BrightRed", "Background": "Black", "Style": "Bold" }.
  4. If loading programmatically, set ConfigurationManager.ThrowOnJsonErrors = false to log-and-continue instead of throwing (the error moves to the JSON error list).

Example fix

// before (broken)
{ "Foreground": "Red", "Bold" }
// after (fixed)
{ "Foreground": "Red", "Style": "Bold" }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the Attribute object shape before handing JSON to ConfigurationManager.
using var doc = JsonDocument.Parse (jsonString);
if (doc.RootElement.ValueKind == JsonTokenType.StartObject
    && doc.RootElement.EnumerateObject ().Any (p => p.Value.ValueKind == JsonTokenType.Number && p.Name is not ("Style")))
{
    // suspect — every Attribute value should be a string/object, not a bare number
}
// Strongest check: parse fully and confirm only known keys.
foreach (var prop in doc.RootElement.EnumerateObject ())
{
    if (prop.Name.ToLower () is not ("foreground" or "background" or "style"))
        throw new InvalidOperationException ($"Unknown Attribute key: {prop.Name}");
}

Try / catch

try { ConfigurationManager.Apply (); }
catch (JsonException ex) when (ex.Message.Contains ("Unexpected token when parsing Attribute"))
{
    // log ex, flag the config file for repair; do not crash the UI
}

Prevention

When it happens

Trigger: 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.).

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/9e529497e9fe38a4. Report an issue: GitHub.