{"record":{"id":"64449a28ddbb7fc1","repo":"apache/hadoop","slug":"id-exists-but-maps-to-and-not","errorCode":null,"errorMessage":"Id {} exists but maps to {} and not {}","messagePattern":"Id (.+?) exists but maps to (.+?) and not (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java","lineNumber":79,"sourceCode":"  byte getNewClasses() {\n    return newClasses;\n  }\n\n  /**\n   * Used to add \"predefined\" classes and by Writable to copy \"new\" classes.\n   */\n  private synchronized void addToMap(Class<?> clazz, byte id) {\n    if (classToIdMap.containsKey(clazz)) {\n      byte b = classToIdMap.get(clazz);\n      if (b != id) {\n        throw new IllegalArgumentException (\"Class \" + clazz.getName() +\n          \" already registered but maps to \" + b + \" and not \" + id);\n      }\n    }\n    if (idToClassMap.containsKey(id)) {\n      Class<?> c = idToClassMap.get(id);\n      if (!c.equals(clazz)) {\n        throw new IllegalArgumentException(\"Id \" + id + \" exists but maps to \" +\n            c.getName() + \" and not \" + clazz.getName());\n      }\n    }\n    classToIdMap.put(clazz, id);\n    idToClassMap.put(id, clazz);\n  }\n  \n  /**\n   * Add a Class to the maps if it is not already present.\n   * @param clazz clazz.\n   */\n  protected synchronized void addToMap(Class<?> clazz) {\n    if (classToIdMap.containsKey(clazz)) {\n      return;\n    }\n    if (newClasses + 1 > Byte.MAX_VALUE) {\n      throw new IndexOutOfBoundsException(\"adding an additional class would\" +\n      \" exceed the maximum number allowed\");","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/AbstractMapWritable.java#L61-L97","documentation":"The mirror check in AbstractMapWritable.addToMap(clazz, id): if the byte id is already bound to a different class, IllegalArgumentException reports both the existing class and the attempted one. Together with the class->id check it guarantees the two maps stay bijective; violation means two classes claim the same wire id.","triggerScenarios":"A custom registration picks an id that collides with a predefined one (AbstractMapWritable's constructor binds -127 through -113); deserializing a stream where the sender assigned that id to a different class because registration order differed; hand-written readFields mixing tables.","commonSituations":"Choosing custom ids like -120 without checking the predefined table; cluster nodes running builds where a new class was inserted in the middle of the registration list, shifting ids.","solutions":["Pick custom fixed ids that do not collide with -127..-113 (the predefined range printed in the AbstractMapWritable constructor)","Make registration order deterministic: static, fixed assignments rather than order-of-first-use","Bump to a fresh set of ids (and drain queues) when changing registrations during upgrades"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// choose custom ids outside the predefined -127..-113 range and unique per class\nstatic final byte ID_TYPE_A = (byte) -100; // verify -100 is not already used","typeGuard":null,"tryCatchPattern":"try {\n  map.readFields(in);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"exists but maps to\")) {\n    // the byte id means a different class on the writer: version/registration mismatch\n  }\n}","preventionTips":["Keep a central registry of class->id assignments in your codebase","Test serialization round-trips between old and new versions during upgrades","Avoid colliding with predefined ids -127..-113 bound by the base constructor"],"tags":["hadoop","serialization","writable","mapwritable","ipc"],"backgroundTag":"writable-class-id-conflict","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}