{"record":{"id":"995ff846de5b7af2","repo":"apache/hadoop","slug":"wrong-key-class-is-not","errorCode":null,"errorMessage":"wrong key class: {} is not {}","messagePattern":"wrong key class: (.+?) is not (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/SequenceFile.java","lineNumber":1473,"sourceCode":"     * @param val input Writable val.\n     * @throws IOException raised on errors performing I/O.\n     */\n    public void append(Writable key, Writable val)\n      throws IOException {\n      append((Object) key, (Object) val);\n    }\n\n    /**\n     * Append a key/value pair.\n     * @param key input Object key.\n     * @param val input Object val.\n     * @throws IOException raised on errors performing I/O.\n     */\n    @SuppressWarnings(\"unchecked\")\n    public synchronized void append(Object key, Object val)\n      throws IOException {\n      if (key.getClass() != keyClass)\n        throw new IOException(\"wrong key class: \"+key.getClass().getName()\n                              +\" is not \"+keyClass);\n      if (val.getClass() != valClass)\n        throw new IOException(\"wrong value class: \"+val.getClass().getName()\n                              +\" is not \"+valClass);\n\n      buffer.reset();\n\n      // Append the 'key'\n      keySerializer.serialize(key);\n      int keyLength = buffer.getLength();\n      if (keyLength < 0)\n        throw new IOException(\"negative length keys not allowed: \" + key);\n\n      // Append the 'value'\n      if (compress == CompressionType.RECORD) {\n        deflateFilter.resetState();\n        compressedValSerializer.serialize(val);\n        deflateOut.flush();","sourceCodeStart":1455,"sourceCodeEnd":1491,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/SequenceFile.java#L1455-L1491","documentation":"Writer.append(Object key, Object val) enforces that key's runtime class is exactly (==, not instanceof) the declared keyClass before serializing; a mismatch throws this IOException naming both classes. Mixing classes would desynchronize the record format since the serializer was built for one specific class, so the writer fails fast instead of producing garbage.","triggerScenarios":"writer.append(new Text(\"x\"), v) on a writer built with Writer.keyClass(LongWritable.class); appending a subclass instance (MyText extends Text) where the header stores Text; call sites whose static types were refactored while the writer options were not.","commonSituations":"keyClass/valueClass options drifting from the appended records during refactors; erased generics hiding mismatches until runtime; reusable record objects of the wrong concrete type passed from a shared loop.","solutions":["Align Writer.keyClass(...) with the concrete class actually appended","If you hold a subclass, copy its fields into an instance of the exact declared class before append","Guard with key.getClass() == writer.getKeyClass() before appending (exact check, matching the writer's semantics)"],"exampleFix":"// before\nWriter w = SequenceFile.createWriter(conf, Writer.file(p),\n    Writer.keyClass(LongWritable.class), Writer.valueClass(Text.class));\nw.append(new Text(\"oops\"), new Text(\"v\")); // wrong key class: Text is not LongWritable\n\n// after\nw.append(new LongWritable(42), new Text(\"v\"));","handlingStrategy":"type-guard","validationCode":"if (key.getClass() != w.getKeyClass()) {\n  throw new IllegalArgumentException(\"key \" + key.getClass() + \" != declared \" + w.getKeyClass());\n}","typeGuard":"static boolean isExactKeyClass(SequenceFile.Writer w, Object key) {\n  return key != null && key.getClass() == w.getKeyClass();\n}","tryCatchPattern":"try {\n  w.append(key, val);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"wrong key class\")) {\n    // record type drift: align writer options or convert the record, then retry\n  } else { throw e; }\n}","preventionTips":["Create the writer with keyClass/valueClass from the same constants used to type the records","In generic code, guard with getClass() == writer.getKeyClass() (exact match, not instanceof, mirroring the writer's semantics)"],"tags":["hadoop","sequence-file","type-mismatch","append"],"backgroundTag":"key-value-class-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}