google/gson · error · JsonSyntaxException

duplicate key

Error message

duplicate key: ${key}

What it means

When Gson deserializes a Map from the array-of-entries JSON form (used with complex map key serialization), MapTypeAdapterFactory checks each key and throws JsonSyntaxException("duplicate key: ...") if a key already exists in the map. This enforces map integrity at deserialization time rather than silently overwriting an entry.

Solutions

  1. Remove duplicate keys at the data source before serialization
  2. Pre-process the JSON (or the JsonElement tree) to deduplicate entries before fromJson
  3. If duplicates are semantically acceptable, deserialize to a List of pairs and dedupe/merge in Java

Example fix

// before - JSON has duplicate keys (array form)
[["k",1],["k",2]]

// after - deduplicated source
[["k",1]]

// or merge duplicates in Java before building the map
Defensive patterns

Strategy: validation

Validate before calling

// Deduplicate keys before deserialization (array-of-entries form)
JsonArray arr = JsonParser.parseString(json).getAsJsonArray();
java.util.Set<String> seen = new java.util.HashSet<>();
JsonArray deduped = new JsonArray();
for (JsonElement e : arr) {
    String k = e.getAsJsonArray().get(0).getAsString();
    if (seen.add(k)) deduped.add(e);
}
Map<String,V> map = gson.fromJson(deduped, mapType);

Try / catch

try {
  Map<K,V> m = gson.fromJson(json, mapType);
} catch (com.google.gson.JsonSyntaxException e) {
  // 'duplicate key': pre-dedupe the source and retry, or deserialize to a List and merge
}

Prevention

When it happens

Trigger: Deserializing to Map<K,V> from JSON shaped like [["k",v1],["k",v2]] (array form) where the same key k appears more than once; data generated without key uniqueness guarantees.

Common situations: Malformed or duplicated source data; aggregation pipelines that emit repeated keys; switching a producer from object form to array form without deduplication.

Related errors


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

Appendix: source

Thrown at gson/src/main/java/com/google/gson/internal/bind/MapTypeAdapterFactory.java:192

    @Override
    public Map<K, V> read(JsonReader in) throws IOException {
      JsonToken peek = in.peek();
      if (peek == JsonToken.NULL) {
        in.nextNull();
        return null;
      }

      Map<K, V> map = constructor.construct();

      if (peek == JsonToken.BEGIN_ARRAY) {
        in.beginArray();
        while (in.hasNext()) {
          in.beginArray(); // entry array
          K key = keyTypeAdapter.read(in);
          V value = valueTypeAdapter.read(in);
          if (map.containsKey(key)) {
            throw new JsonSyntaxException("duplicate key: " + key);
          }
          map.put(key, value);
          in.endArray();
        }
        in.endArray();
      } else {
        in.beginObject();
        while (in.hasNext()) {
          JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
          K key = keyTypeAdapter.read(in);
          V value = valueTypeAdapter.read(in);
          if (map.containsKey(key)) {
            throw new JsonSyntaxException("duplicate key: " + key);
          }
          map.put(key, value);
        }
        in.endObject();
      }

View on GitHub (pinned to 310ac341f2)