google/gson · error · JsonSyntaxException

Lossy conversion from " + intValue + " to short; at path " +

Error message

Lossy conversion from " + intValue + " to short; at path " + in.getPreviousPath()

What it means

The SHORT TypeAdapter reads an integer and rejects values outside [-32768, 65535] (the 65535 upper bound supports unsigned short). Anything wider is reported as a lossy conversion with JsonSyntaxException including the value and previous path.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java:242

  public static final TypeAdapter<Number> SHORT =
      new TypeAdapter<Number>() {
        @Override
        public Number read(JsonReader in) throws IOException {
          if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
          }

          int intValue;
          try {
            intValue = in.nextInt();
          } catch (NumberFormatException e) {
            throw new JsonSyntaxException(e);
          }
          // Allow up to 65535 to support unsigned values
          if (intValue > 65535 || intValue < Short.MIN_VALUE) {
            throw new JsonSyntaxException(
                "Lossy conversion from " + intValue + " to short; at path " + in.getPreviousPath());
          }
          return (short) intValue;
        }

        @Override
        public void write(JsonWriter out, Number value) throws IOException {
          if (value == null) {
            out.nullValue();
          } else {
            out.value(value.shortValue());
          }
        }
      };

  public static final TypeAdapterFactory SHORT_FACTORY =
      newFactory(short.class, Short.class, SHORT);

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Change the field type from short/Short to int.
  2. Constrain the upstream value to the short range before serialization.
  3. Register a custom TypeAdapter<Number> for Short that clamps.
  4. Re-evaluate whether the field genuinely needs to be a short.

Example fix

// before
class Endpoint { short port; }
gson.fromJson("{\"port\":70000}", Endpoint.class); // throws

// after
class Endpoint { int port; }
Defensive patterns

Strategy: validation

Validate before calling

int v = JsonParser.parseString(json).getAsJsonObject().get("port").getAsInt();
if (v > 65535 || v < Short.MIN_VALUE) throw new IllegalArgumentException("Lossy short: " + v);

Type guard

null

Try / catch

try {
  gson.fromJson(json, Endpoint.class);
} catch (JsonSyntaxException e) {
  if (e.getMessage().startsWith("Lossy conversion from") && e.getMessage().contains("to short")) {
    // widen the field type to int and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Deserialifying a JSON number like 70000 or -40000 into a short/Short field; receiving identifiers or port-like values that overflow a short; signed/unsigned boundary confusion. Triggered at line 242.

Common situations: Port numbers beyond 32767 stored as short; year fields approaching overflow; counters that exceed short range; cross-language protocols with different numeric widths.

Related errors


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