{"record":{"id":"c52af6f38ce917a4","repo":"apache/hadoop","slug":"incorrect-state-to-start-a-new-key-state","errorCode":null,"errorMessage":"Incorrect state to start a new key: {state}","messagePattern":"Incorrect state to start a new key: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java","lineNumber":542,"sourceCode":"    }\n\n    /**\n     * Obtain an output stream for writing a key into TFile. This may only be\n     * called when there is no active Key appending stream or value appending\n     * stream.\n     * \n     * @param length\n     *          The expected length of the key. If length of the key is not\n     *          known, set length = -1. Otherwise, the application must write\n     *          exactly as many bytes as specified here before calling close on\n     *          the returned output stream.\n     * @return The key appending output stream.\n     * @throws IOException raised on errors performing I/O.\n     * \n     */\n    public DataOutputStream prepareAppendKey(int length) throws IOException {\n      if (state != State.READY) {\n        throw new IllegalStateException(\"Incorrect state to start a new key: \"\n            + state.name());\n      }\n\n      initDataBlock();\n      DataOutputStream ret = new KeyRegister(length);\n      state = State.IN_KEY;\n      return ret;\n    }\n\n    /**\n     * Obtain an output stream for writing a value into TFile. This may only be\n     * called right after a key appending operation (the key append stream must\n     * be closed).\n     * \n     * @param length\n     *          The expected length of the value. If length of the value is not\n     *          known, set length = -1. Otherwise, the application must write\n     *          exactly as many bytes as specified here before calling close on","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/file/tfile/TFile.java#L524-L560","documentation":"Thrown by TFile.Writer.prepareAppendKey(int) when the writer's state is anything other than READY: either a previous key/value append stream is still open, or the writer is closed/otherwise mid-transition. TFile.Writer is a strict state machine (READY -> IN_KEY -> END_KEY -> IN_VALUE -> READY), and each step's preparatory call validates the current state, surfacing violations as IllegalStateException with the offending state name in the message.","triggerScenarios":"Calling prepareAppendKey() twice without closing the first stream; calling it before closing the value stream of the previous record; calling it after an append stream failed mid-write and was never closed.","commonSituations":"Loop bodies that reuse a variable for the key stream without closing the previous iteration's stream; exception paths that skip the inner stream close; refactoring a single append into staged prepare calls and forgetting one close.","solutions":["Always close the stream returned by prepareAppendKey/prepareAppendValue before starting the next record, using try-with-resources","Prefer writer.append(key, value), which performs the whole READY->READY cycle internally","Treat any IllegalStateException here as a logic bug in the calling loop, not as a retryable condition"],"exampleFix":"// before\nDataOutputStream k = writer.prepareAppendKey(-1);\nk.write(key1);\nDataOutputStream k2 = writer.prepareAppendKey(-1); // IllegalStateException: IN_KEY\n\n// after\ntry (DataOutputStream k = writer.prepareAppendKey(-1)) {\n  k.write(key1);\n}\nDataOutputStream k2 = writer.prepareAppendKey(-1); // OK: back to READY","handlingStrategy":"validation","validationCode":"// Enforce one complete record per iteration; state returns to READY each time\nwhile (records.hasNext()) {\n  Record r = records.next();\n  try (DataOutputStream k = writer.prepareAppendKey(r.keyLength())) {\n    k.write(r.keyBytes());\n  }\n  try (DataOutputStream v = writer.prepareAppendValue(r.valueLength())) {\n    v.write(r.valueBytes());\n  }\n}","typeGuard":null,"tryCatchPattern":"catch (IllegalStateException e) {\n  // message ends with the writer state, e.g. 'IN_KEY': an inner stream was left open.\n  // close outstanding streams, then close the writer; do not continue appending.\n}","preventionTips":["Prefer writer.append(key, value) over manual prepare/close pairs","Keep prepareAppendKey and its close in the same lexical scope (try-with-resources)","Never reuse a key-stream variable across loop iterations without closing it"],"tags":["hadoop","tfile","state-machine","writer"],"backgroundTag":"illegal-state-transition","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}