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

  1. Change the field type from char/Character to String if multi-character values are expected.
  2. Sanitize the source to emit exactly one character (or empty -> '\u0000').
  3. Register a custom TypeAdapter<Character> that picks the first char or maps empty to a default.
  4. 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

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


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/04d04c99f2f3278d.json. Report an issue: GitHub.