google/gson · error · JsonSyntaxException

Expecting number, got: ${jsonToken}; at path ${path}

Error message

Expecting number, got: ${jsonToken}; at path ${path}

What it means

NumberTypeAdapter handles fields/variables typed as Number. Its read() accepts only NULL, NUMBER, or STRING (numeric) tokens; any other token (BOOLEAN, BEGIN_OBJECT, BEGIN_ARRAY, NAME, END_*) is a type mismatch and Gson throws JsonSyntaxException with the offending token and the reader path. This guards against silently coercing incompatible JSON into a numeric Java field.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/NumberTypeAdapter.java:73

    if (toNumberStrategy == ToNumberPolicy.LAZILY_PARSED_NUMBER) {
      return LAZILY_PARSED_NUMBER_FACTORY;
    } else {
      return newFactory(toNumberStrategy);
    }
  }

  @Override
  public Number read(JsonReader in) throws IOException {
    JsonToken jsonToken = in.peek();
    switch (jsonToken) {
      case NULL:
        in.nextNull();
        return null;
      case NUMBER:
      case STRING:
        return toNumberStrategy.readNumber(in);
      default:
        throw new JsonSyntaxException(
            "Expecting number, got: " + jsonToken + "; at path " + in.getPath());
    }
  }

  @Override
  public void write(JsonWriter out, Number value) throws IOException {
    out.value(value);
  }
}

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Fix the source data to send a numeric JSON value for Number-typed fields
  2. Register a custom TypeAdapter<Number> that coerces or nulls incompatible tokens
  3. Deserialize the field as Object and post-process, or use a more permissive target type

Example fix

// before - boolean where Number expected
{"count": true}

// after - numeric value
{"count": 1}
Defensive patterns

Strategy: type-guard

Validate before calling

// Inspect the token before binding a Number field
JsonReader reader = ...;
JsonToken t = reader.peek();
if (t == JsonToken.NUMBER || t == JsonToken.STRING || t == JsonToken.NULL) {
    Number n = gson.fromJson(reader, Number.class);
} else {
    // schema drift: handle, default, or skip
    reader.skipValue();
}

Type guard

// Narrow a JsonElement to a numeric value before binding
static boolean isNumeric(JsonElement e) {
    return e != null && e.isJsonPrimitive() && e.getAsJsonPrimitive().isNumber();
}

Try / catch

try {
  Number n = gson.fromJson(json, Number.class);
} catch (com.google.gson.JsonSyntaxException e) {
  // 'Expecting number, got: <token>': source sent a non-numeric; coerce or skip
}

Prevention

When it happens

Trigger: Deserializing JSON where a Number-typed field receives a boolean, object, or array; e.g. {"count": true} mapped to a Number field, or {"amount": {}} where a number was expected.

Common situations: Schema drift where a numeric field arrives as a different JSON type; weakly-typed Object payloads later narrowed to Number; producer bugs emitting the wrong value type.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/0caa9e97640c53f1. Report an issue: GitHub.