google/gson · error · JsonSyntaxException
Expecting character, got: " + str + "; at " + in.getPrevious
Error message
Expecting character, got: " + str + "; at " + in.getPreviousPath()
What it means
The CHARACTER TypeAdapter reads a JSON string and expects exactly one character. If the string length is not 1 (empty, or two+ characters), Gson throws JsonSyntaxException with the offending string and previous path. A null token is handled separately (returns null), so this fires only on non-empty multi-char or empty strings.
Source
Thrown at gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java:542
}
public static final TypeAdapter<Number> FLOAT = new FloatAdapter(false);
public static final TypeAdapter<Number> FLOAT_STRICT = new FloatAdapter(true);
public static final TypeAdapter<Number> DOUBLE = new DoubleAdapter(false);
public static final TypeAdapter<Number> DOUBLE_STRICT = new DoubleAdapter(true);
public static final TypeAdapter<Character> CHARACTER =
new TypeAdapter<Character>() {
@Override
public Character read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String str = in.nextString();
if (str.length() != 1) {
throw new JsonSyntaxException(
"Expecting character, got: " + str + "; at " + in.getPreviousPath());
}
return str.charAt(0);
}
@Override
public void write(JsonWriter out, Character value) throws IOException {
out.value(value == null ? null : String.valueOf(value));
}
};
public static final TypeAdapterFactory CHARACTER_FACTORY =
newFactory(char.class, Character.class, CHARACTER);
public static final TypeAdapter<String> STRING =
new TypeAdapter<String>() {
@Override
public String read(JsonReader in) throws IOException {View on GitHub (pinned to 8b8628c656)
Solutions
- Change the field type from char/Character to String if multi-character values are expected.
- Sanitize the source to emit exactly one character (or empty -> '\u0000').
- Register a custom TypeAdapter<Character> that picks the first char or maps empty to a default.
- Validate the JSON value length before deserialization.
Example fix
// before
class Flag { char code; }
gson.fromJson("{\"code\":\"OK\"}", Flag.class); // throws
// after
class Flag { String code; }
// or custom adapter
registerTypeAdapter(char.class, new TypeAdapter<Character>() {
public Character read(JsonReader r) throws IOException {
String s = r.nextString(); return s.isEmpty() ? '\0' : s.charAt(0);
}
public void write(JsonWriter w, Character c) throws IOException { w.value(String.valueOf(c)); }
}.nullSafe()); Defensive patterns
Strategy: validation
Validate before calling
// Validate single-char constraint before deserializing into a char field
String s = JsonParser.parseString(json).getAsJsonObject().get("code").getAsString();
if (s == null || s.length() != 1) throw new IllegalArgumentException("Expecting char, got: " + s); Type guard
null
Try / catch
try {
gson.fromJson(json, Flag.class);
} catch (JsonSyntaxException e) {
if (e.getMessage().startsWith("Expecting character, got:")) {
// widen field to String or sanitize to first char
} else throw e;
} Prevention
- Model free-text fields as String, not char.
- Validate source length at the trust boundary.
- Register a tolerant char adapter if single-char semantics are intentional.
When it happens
Trigger: Deserialifying a JSON string value into a char/Character field where the value is empty ("") or has more than one character (e.g., "ab"). Triggered at line 542 when str.length()!=1.
Common situations: API fields returning full words or codes for what was modeled as a single char; empty-string defaults from optional fields; unicode code points represented as surrogate pairs (two chars); status fields that grew beyond one character.
Related errors
- Invalid bitset value " + intValue + ", expected 0 or 1; at p
- Invalid style: {style}
- duplicate key: {key}
- Expecting number, got: " + jsonToken + "; at path " + in.get
- Unexpected token: " + peeked
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/04d04c99f2f3278d.json.
Report an issue: GitHub.