tui-cs/Terminal.Gui · error · JsonException

Unexpected StartObject token when parsing Scheme: {reader.To

Error message

Unexpected StartObject token when parsing Scheme: {reader.TokenType}.

What it means

SchemeJsonConverter.Read expects a JSON object (the Scheme's named VisualRole attributes). If the token at that position is not StartObject — a string, number, array, or true/false where a Scheme object was expected — it throws.

Source

Thrown at Terminal.Gui/Configuration/SchemeJsonConverter.cs:15

using System.Text.Json;
using System.Text.Json.Serialization;

namespace Terminal.Gui.Configuration;

// ReSharper disable StringLiteralTypo
/// <summary>Implements a JSON converter for <see cref="Drawing.Scheme"/>.</summary>
internal class SchemeJsonConverter : JsonConverter<Scheme>
{
    /// <inheritdoc/>
    public override Scheme Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.StartObject)
        {
            throw new JsonException ($"Unexpected StartObject token when parsing Scheme: {reader.TokenType}.");
        }

        var scheme = new Scheme ();
        var propertyName = string.Empty;

        while (reader.Read ())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
            {
                return scheme;
            }

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

            propertyName = reader.GetString ();

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Wrap the value in an object with VisualRole keys, e.g. { "Normal": { ... } }.
  2. Copy a known-good Scheme object from the default theme and edit it.

Example fix

// before
"Base": "Red"
// after
"Base": { "Normal": { "Foreground": "Red", "Background": "Black" } }
Defensive patterns

Strategy: validation

Validate before calling

using var doc = JsonDocument.Parse (configText);
foreach (JsonProperty scheme in doc.RootElement.GetProperty ("Schemes").EnumerateObject ())
{
    if (scheme.Value.ValueKind != JsonValueKind.Object)
        return false; // each Scheme must be an object
}
return true;

Try / catch

try { ConfigurationManager.Apply (); }
catch (JsonException ex) when (ex.Message.Contains ("Unexpected StartObject token when parsing Scheme"))
{ /* report which Scheme name mapped to a non-object */ }

Prevention

When it happens

Trigger: A "Schemes" entry mapped to a non-object, e.g. "Base": "red" or "Base": 5 instead of "Base": { "Normal": { ... } }.

Common situations: Misunderstanding that each Scheme must be an object of role→Attribute pairs (shorthand notation is not supported); YAML flow-scalar collapse.

Related errors


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