BCUninstaller/Bulk-Crap-Uninstaller · error · JsonException

Expected string or array token but got {reader.TokenType}

Error message

Expected string or array token but got {reader.TokenType}

What it means

A JsonException thrown by `DynamicStringArrayConverter.Read` when the current JSON token is neither a string nor the start of an array. The converter is designed to accept either a single string or a string array for a property and normalize both into `string[]`; any other token type (number, object, boolean, null token) is invalid for that contract and is rejected.

Source

Thrown at source/UninstallTools/Factory/Json/DynamicStringArrayConverter.cs:26

    /// <summary>
    /// Handle JSON string array entry that has one dimension less or more.
    /// </summary>
    internal class DynamicStringArrayConverter : JsonConverter<string[]>
    {
        public override string[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 0-dimension
            if (reader.TokenType == JsonTokenType.String)
                return new[] { reader.GetString() };

            if (reader.TokenType == JsonTokenType.StartArray)
            {
                var results = new List<string>();
                ReadStrings(ref reader, results);
                return results.ToArray();
            }

            throw new JsonException($"Expected string or array token but got {reader.TokenType}");
        }

        private static void ReadStrings(ref Utf8JsonReader reader, List<string> results)
        {
            while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
            {
                switch (reader.TokenType)
                {
                    // normal
                    case JsonTokenType.String:
                        results.Add(reader.GetString());
                        break;

                    // nested
                    case JsonTokenType.StartArray:
                        var first = ReadFirstString(ref reader);
                        if (first != null)
                            results.Add(first);

View on GitHub (pinned to 608321de98)

Solutions

  1. Inspect the offending JSON at the reported token and convert the value to a string or array of strings.
  2. Re-export the data from a trusted source to ensure schema compliance.
  3. Pre-process the JSON to coerce unexpected scalar values to strings before deserialization.

Example fix

// before
"UninstallerString": 12345
// after
"UninstallerString": "12345"
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the token type before the converter runs (schema check).
using var doc = JsonDocument.Parse(json);
foreach (var prop in doc.RootElement.EnumerateObject())
    if (prop.Value.ValueType is JsonValueType.Number or JsonValueType.False or JsonValueType.True or JsonValueType.Null)
        /* coerce or reject scalar where string/array expected */

Type guard

bool IsStringOrArray(JsonElement el) => el.ValueType is JsonValueType.String or JsonValueType.Array;

Try / catch

try { var data = JsonSerializer.Deserialize<T>(json, options); }
catch (JsonException ex) when (ex.Message.Contains("Expected string or array token"))
{ /* log the offending property, sanitize/repair the JSON, retry */ }

Prevention

When it happens

Trigger: Deserializing a JSON document where a field declared as a string-or-string-array instead contains a number, boolean, nested object, or explicit null. This occurs in the uninstaller's JSON import paths (e.g. exporting/importing the app list) when the source JSON does not match the expected schema.

Common situations: Hand-edited or third-party-exported JSON with inconsistent value types; a schema change where a field that used to be a string is now an object; null values where the converter expects a token it can read.

Related errors


AI-assisted analysis of BCUninstaller/Bulk-Crap-Uninstaller@608321de98 (2026-08-13). Data as JSON: /api/errors/fdee1e3fe55eedf9. Report an issue: GitHub.