tui-cs/Terminal.Gui · error · JsonException

{propertyName}: Bad Attribute.

Error message

{propertyName}: Bad Attribute.

What it means

Thrown at the end of AttributeJsonConverter.Read if the reader loop exits without ever hitting an EndObject token — i.e. the JSON stream ended mid-Attribute (truncated input). The loop `while (reader.Read())` terminates because there are no more tokens, so the object was never closed.

Source

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

                        }
                        catch (ArgumentException ex)
                        {
                            throw new JsonException ("Expected a valid text style value.", ex);
                        }

                        break;

                    default:
                        throw new JsonException ($"{propertyName}: Unknown Attribute property .");
                }
            }
            catch (JsonException ex)
            {
                throw new JsonException ($"{propertyName}: \"{property}\" - {ex.Message}");
            }
        }

        throw new JsonException ($"{propertyName}: Bad Attribute.");
    }

    public override void Write (Utf8JsonWriter writer, Attribute value, JsonSerializerOptions options)
    {
        writer.WriteStartObject ();
        writer.WritePropertyName (nameof (Attribute.Foreground));
        ColorJsonConverter.Instance.Write (writer, value.Foreground, options);
        writer.WritePropertyName (nameof (Attribute.Background));
        ColorJsonConverter.Instance.Write (writer, value.Background, options);
        if (value.Style != TextStyle.None)
        {
            writer.WritePropertyName (nameof (Attribute.Style));
            writer.WriteStringValue (value.Style.ToString ());
        }

        writer.WriteEndObject ();
    }
}

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Round-trip the JSON through a parser (System.Text.Json.JsonDocument.Parse) before handing it to ConfigurationManager to confirm it is complete and well-formed.
  2. Open the file and confirm every `{` has a matching `}`.
  3. Regenerate the config from a known-good source.

Example fix

// before (truncated)
{ "Foreground": "Red", "Background": "Black"
// after
{ "Foreground": "Red", "Background": "Black" }
Defensive patterns

Strategy: validation

Validate before calling

// Reject truncated JSON up front.
using var doc = JsonDocument.Parse (jsonString); // throws JsonException if truncated
// If you also want to assert the Attribute object closed:
if (doc.RootElement.TryGetProperty ("SomeAttr", out var a)
    && a.ValueKind != JsonValueKind.Object)
    throw new FormatException ("Attribute is not a complete JSON object.");

Try / catch

try { ConfigurationManager.Apply (); }
catch (JsonException ex) when (ex.Message.EndsWith ("Bad Attribute."))
{ /* config is truncated; re-fetch/re-save the file */ }

Prevention

When it happens

Trigger: Truncated config JSON (file cut off, network stream ended early, StringBuilder incomplete). The Attribute object has no closing brace and the reader runs out of tokens.

Common situations: A config file was partially written (interrupted save); a manually pasted JSON fragment missing the closing `}`; a templating system that dropped the tail.

Related errors


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