{"record":{"id":"cff07e003bc3d546","repo":"google/gson","slug":"failed-parsing-s-as-uuid-at-path-path","errorCode":null,"errorMessage":"Failed parsing '${s}' as UUID; at path ${path}","messagePattern":"Failed parsing '(.+?)' as UUID; at path (.+?)","errorType":"exception","errorClass":"JsonSyntaxException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java","lineNumber":794,"sourceCode":"        }\n      };\n\n  public static final TypeAdapterFactory INET_ADDRESS_FACTORY =\n      newTypeHierarchyFactory(InetAddress.class, INET_ADDRESS);\n\n  public static final TypeAdapter<UUID> UUID =\n      new TypeAdapter<UUID>() {\n        @Override\n        public UUID read(JsonReader in) throws IOException {\n          if (in.peek() == JsonToken.NULL) {\n            in.nextNull();\n            return null;\n          }\n          String s = in.nextString();\n          try {\n            return java.util.UUID.fromString(s);\n          } catch (IllegalArgumentException e) {\n            throw new JsonSyntaxException(\n                \"Failed parsing '\" + s + \"' as UUID; at path \" + in.getPreviousPath(), e);\n          }\n        }\n\n        @Override\n        public void write(JsonWriter out, UUID value) throws IOException {\n          out.value(value == null ? null : value.toString());\n        }\n      };\n\n  public static final TypeAdapterFactory UUID_FACTORY = newFactory(UUID.class, UUID);\n\n  public static final TypeAdapter<Currency> CURRENCY =\n      new TypeAdapter<Currency>() {\n        @Override\n        public Currency read(JsonReader in) throws IOException {\n          String s = in.nextString();\n          try {","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java#L776-L812","documentation":"Thrown by Gson's UUID TypeAdapter when java.util.UUID.fromString cannot parse the JSON string. UUID.fromString requires the canonical 8-4-4-4-12 hex form (with or without surrounding braces in some JDKs); any deviation throws IllegalArgumentException, which Gson wraps as a JsonSyntaxException with the path.","triggerScenarios":"Deserializing a field of type java.util.UUID from a JSON string that is malformed: wrong length, missing hyphens (\"550e8400e1b841d4a716446655440000\"), containing non-hex characters, extra whitespace, or a value like \"null\" that is not the JSON null token.","commonSituations":"Upstream services emitting UUIDs without hyphens or in uppercase with different grouping; copying IDs with leading/trailing spaces; mixing UUID and ULID/ObjectId formats; quoting the literal string \"null\" instead of emitting JSON null.","solutions":["Validate and normalize the UUID string before Gson sees it (strip whitespace, insert hyphens for compact forms, lowercase hex).","Fix the upstream producer to emit canonical UUIDs (java.util.UUID.toString or equivalent).","Register a custom TypeAdapter<UUID> that accepts multiple formats (compact, braced, URN \"urn:uuid:...\") and normalizes before calling UUID.fromString.","If null is meaningful, ensure the producer emits JSON null, not the string \"null\"."],"exampleFix":"// before\npublic class Order { public UUID id; }\n// JSON: {\"id\":\"550e8400e1b841d4a716446655440000\"} -> fails (no hyphens)\n\n// after: custom adapter normalizing compact UUIDs\nGson g = new GsonBuilder()\n  .registerTypeHierarchyAdapter(UUID.class, new TypeAdapter<UUID>() {\n    public UUID read(JsonReader in) throws IOException {\n      String s = in.nextString().replace(\"urn:uuid:\",\"\").replace(\"-\",\"\").trim();\n      if (s.length() != 32) throw new JsonSyntaxException(\"bad uuid: \"+s);\n      String f = s.replaceFirst(\"(\\\\w{8})(\\\\w{4})(\\\\w{4})(\\\\w{4})(\\\\w{12})\", \"$1-$2-$3-$4-$5\");\n      return java.util.UUID.fromString(f);\n    }\n    public void write(JsonWriter out, UUID v) throws IOException { out.value(v==null?null:v.toString()); }\n  }).create();","handlingStrategy":"validation","validationCode":"private static final Pattern UUID_LIKE =\n  Pattern.compile(\"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$\");\nString raw = jsonNode.get(\"id\").getAsString();\nif (raw != null && !UUID_LIKE.matcher(raw.trim()).matches()) {\n  throw new IllegalArgumentException(\"Not a canonical UUID: \" + raw);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return gson.fromJson(json, HasId.class);\n} catch (JsonSyntaxException e) {\n  if (e.getMessage().contains(\"as UUID\")) {\n    // normalize or reject; e.g. strip hyphens and reformat, or drop record\n    throw new IllegalArgumentException(\"Malformed UUID in payload\", e);\n  }\n  throw e;\n}","preventionTips":["Validate UUID strings with a canonical-format regex before Gson.","Use java.util.UUID.fromString in tests against sample inputs to catch format drift early.","Have producers emit UUID.toString() to guarantee canonical form.","Distinguish JSON null from the literal \"null\" string in your contract."],"tags":["gson","parsing","uuid","json-syntax-exception","type-adapter"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}