{"record":{"id":"22da5e7d4ea12834","repo":"apache/flink","slug":"you-must-have-forgotten-to-call-open-on-your-inp","errorCode":null,"errorMessage":"You must have forgotten to call open() on your input format.","messagePattern":"You must have forgotten to call open\\(\\) on your input format\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/api/common/io/BinaryInputFormat.java","lineNumber":397,"sourceCode":"                offset += read;\n                if (this.blockPos >= this.maxPayloadSize) {\n                    this.skipHeader();\n                }\n                remainingLength -= read;\n            }\n            return totalRead;\n        }\n    }\n\n    // --------------------------------------------------------------------------------------------\n    //  Checkpointing\n    // --------------------------------------------------------------------------------------------\n\n    @PublicEvolving\n    @Override\n    public Tuple2<Long, Long> getCurrentState() throws IOException {\n        if (this.blockBasedInput == null) {\n            throw new RuntimeException(\n                    \"You must have forgotten to call open() on your input format.\");\n        }\n\n        return new Tuple2<>(\n                this.blockBasedInput.getCurrBlockPos(), // the last read index in the block\n                this.readRecords // the number of records read\n                );\n    }\n\n    @PublicEvolving\n    @Override\n    public void reopen(FileInputSplit split, Tuple2<Long, Long> state) throws IOException {\n        Preconditions.checkNotNull(split, \"reopen() cannot be called on a null split.\");\n        Preconditions.checkNotNull(state, \"reopen() cannot be called with a null initial state.\");\n\n        try {\n            this.open(split);\n        } finally {","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/api/common/io/BinaryInputFormat.java#L379-L415","documentation":"BinaryInputFormat.getCurrentState() (used for checkpointing the input format's progress) reads position and record count from the internal blockBasedInput. That field is only initialized by open(FileInputSplit). If getCurrentState is called before open completes (blockBasedInput == null), the format throws RuntimeException with a 'forgot to call open()' message, because there is no valid checkpoint state to return.","triggerScenarios":"Invoking format.getCurrentState() before format.open(split); or a checkpoint trigger firing before the source operator opened its split; or a custom driver/test that calls the CheckpointableInputFormat lifecycle out of order.","commonSituations":"Manual unit testing of checkpointable input formats without driving open() first; a race where a checkpoint barrier arrives during operator initialization before open() finished; incorrect custom source wrapping a BinaryInputFormat.","solutions":["Ensure open(split) is called and completes before any getCurrentState()/reopen() invocation (the runtime normally guarantees this).","In custom drivers/tests, follow the lifecycle: configure -> open(split) -> [nextRecord...] -> getCurrentState() -> reopen(split, state).","If writing a custom source wrapping this format, defer/skip the checkpoint until the format reports it is open."],"exampleFix":"// before\nTuple2<Long,Long> state = format.getCurrentState(); // blockBasedInput == null -> throws\n\n// after\nformat.open(split);\n// ... read records ...\nTuple2<Long,Long> state = format.getCurrentState();","handlingStrategy":"validation","validationCode":"// Only checkpoint state after open has initialized the block input.\nif (format.getBlockBasedInput() != null) { // assumes accessor or package-private visibility\n    Tuple2<Long, Long> state = format.getCurrentState();\n} else {\n    // skip / return empty state\n}","typeGuard":null,"tryCatchPattern":"try {\n    Tuple2<Long, Long> state = format.getCurrentState();\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"call open()\")) {\n        // format not opened yet; no checkpoint state to store\n    } else {\n        throw e;\n    }\n}","preventionTips":["Drive the CheckpointableInputFormat lifecycle strictly: configure -> open -> read -> getCurrentState -> reopen.","In custom sources, only snapshot state after the operator reports it is open.","Unit-test the lifecycle in order rather than calling getCurrentState in isolation."],"tags":["input-format","binary","lifecycle","checkpoint","open"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}