memstechtips/Winhance · error · JsonException
Unexpected token type {reader.TokenType} when reading string
Error message
Unexpected token type {reader.TokenType} when reading string array. What it means
JsonException from StringOrStringArrayConverter.Read when the JSON token at the property position is neither null, a string, nor the start of an array. The converter exists to accept either a single string or a string[] for AppxPackageName backward-compat; anything else (a number, boolean, object, or raw value) is rejected as malformed.
Source
Thrown at src/Winhance.Core/Features/Common/Converters/StringOrStringArrayConverter.cs:42
if (reader.TokenType == JsonTokenType.StartArray)
{
var list = new List<string>();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray)
break;
if (reader.TokenType == JsonTokenType.String)
{
var item = reader.GetString();
if (item != null)
list.Add(item);
}
}
return list.ToArray();
}
throw new JsonException($"Unexpected token type {reader.TokenType} when reading string array.");
}
public override void Write(Utf8JsonWriter writer, string[]? value, JsonSerializerOptions options)
{
if (value == null)
{
writer.WriteNullValue();
return;
}
writer.WriteStartArray();
foreach (var item in value)
{
writer.WriteStringValue(item);
}
writer.WriteEndArray();
}
}
View on GitHub (pinned to f23d554eb2)
Solutions
- Open the config JSON and find the property the converter is reading; ensure its value is a string, null, or array of strings.
- Quote numeric package names: change `"AppxPackageName": 12345` to `"AppxPackageName": "12345"`.
- Re-export the config from a known-good Winhance install to regenerate a schema-valid file.
- Tolerate the malformed input by coercion in the converter (see exampleFix) only if backward-compat is required.
Example fix
// before: only null/string/array accepted; numbers/bools/object throw
throw new JsonException($"Unexpected token type {reader.TokenType} when reading string array.");
// after: coerce numbers/bools to their string form for resilience, still reject objects
if (reader.TokenType == JsonTokenType.Number || reader.TokenType == JsonTokenType.True || reader.TokenType == JsonTokenType.False)
return new[] { reader.GetRawText() };
throw new JsonException($"Unexpected token type {reader.TokenType} when reading string array."); Defensive patterns
Strategy: validation
Validate before calling
// Before deserializing, schema-check that AppxPackageName is string/array/null.
using var doc = JsonDocument.Parse(jsonText);
if (doc.RootElement.TryGetProperty("AppxPackageName", out var el))
if (el.ValueKind is not (JsonValueKind.String or JsonValueKind.Array or JsonValueKind.Null))
return; // reject the file before deserialization Try / catch
catch (System.Text.Json.JsonException ex) when (ex.Message.Contains("Unexpected token type"))
{
// Report the path/line from ex; tell the user which property has the wrong JSON value kind.
} Prevention
- Quote numeric values in config JSON (treat package names as strings).
- Re-export configs from a known-good Winhance install.
- Coerce non-string scalars in the converter only as an explicit backward-compat decision.
When it happens
Trigger: Deserializing a config/settings JSON where a property typed as string[] (with the converter attached) holds a non-string scalar — e.g. `"AppxPackageName": 123`, `"AppxPackageName": true`, or `"AppxPackageName": {"Name":"..."}`. The reader is positioned at that token and none of the null/string/startarray branches match.
Common situations: A config file exported by a different/older Winhance version serialized the field as a number or object. A user hand-edited the JSON and put a non-string. A schema migration left a stale value type. A numeric-only package name was serialized without quotes by a broken exporter.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of memstechtips/Winhance@f23d554eb2 (2026-08-13).
Data as JSON: /api/errors/e60272006f7b7f04.
Report an issue: GitHub.