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
- 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.
- Open the file and confirm every `{` has a matching `}`.
- 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
- Always JsonDocument.Parse config before Load to catch truncation.
- Write config files atomically (temp file + rename) to avoid partial writes.
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
- {propertyName}: Unexpected token when parsing Attribute: {re
- {propertyName}: Expected a string value.
- Expected a valid text style value.
- {propertyName}: Unknown Attribute property .
- {propertyName}: "{property}" - {ex.Message}
AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13).
Data as JSON: /api/errors/9a718aaab0058db9.
Report an issue: GitHub.