{"record":{"id":"8339e4ac69040d2f","repo":"apache/shardingsphere","slug":"invalid-batch-handle-statement-handle-d-8339e4","errorCode":null,"errorMessage":"Invalid batch handle: statement handle %d","messagePattern":"Invalid batch handle: statement handle (.+?)","errorType":"exception","errorClass":"InvalidBatchHandleException","httpStatus":null,"severity":"error","filePath":"proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchMessageCommandExecutor.java","lineNumber":51,"sourceCode":"import java.util.Collections;\nimport java.util.List;\n\n/**\n * Batch send message command executor for Firebird.\n */\n@RequiredArgsConstructor\npublic final class FirebirdBatchMessageCommandExecutor implements CommandExecutor {\n    \n    private final FirebirdBatchMessageCommandPacket packet;\n    \n    private final ConnectionSession connectionSession;\n    \n    @Override\n    public Collection<DatabasePacket> execute() throws SQLException {\n        int connectionId = connectionSession.getConnectionId();\n        FirebirdBatchStatement batchStatement = FirebirdBatchRegistry.getInstance().getBatchStatement(connectionId, packet.getStatementHandle());\n        if (null == batchStatement) {\n            throw new InvalidBatchHandleException(packet.getStatementHandle());\n        }\n        if (batchStatement.getAccumulatedSize() + packet.getDataLength() > batchStatement.getBufferSize()) {\n            throw new BatchTooBigException(packet.getStatementHandle(), batchStatement.getAccumulatedSize(), packet.getDataLength(), batchStatement.getBufferSize());\n        }\n        for (List<Object> each : packet.readParameterValues(batchStatement.getColumnDescriptors())) {\n            batchStatement.addParameterValues(each);\n        }\n        batchStatement.addSize(packet.getDataLength());\n        return Collections.singleton(new FirebirdGenericResponsePacket());\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":63,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchMessageCommandExecutor.java#L33-L63","documentation":"InvalidBatchHandleException thrown by FirebirdBatchMessageCommandExecutor when a batch MESSAGE packet references a statement handle with no open batch in FirebirdBatchRegistry for the current connection. Identical guard to the execute executor: MESSAGE rows can only be appended to an existing batch.","triggerScenarios":"FirebirdBatchMessageCommandExecutor.execute() does getBatchStatement(connectionId, packet.getStatementHandle()) and throws when null; sending batch data before CREATE BATCH succeeded, or after the batch was closed/freed.","commonSituations":"fire-and-forget clients that pipeline MESSAGE before reading the CREATE BATCH response; retry after a timeout where the batch was already freed; pooled connection switch between create and append.","solutions":["Wait for the CREATE BATCH generic response before streaming MESSAGE packets for that handle.","On timeout/uncertainty, close and recreate the batch rather than continuing to send messages.","Keep the whole batch lifecycle on one physical connection."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Wait for CREATE BATCH ack before streaming messages\nif (!openBatches.contains(stmtHandle)) throw new IllegalStateException(\"create batch first\");\nsendBatchMessage(stmtHandle, data);","typeGuard":null,"tryCatchPattern":"catch (SQLException e) {\n    if (e.getMessage().contains(\"Invalid batch handle\")) { int h = sendCreateBatch(currentPreparedHandle()); resendPendingMessages(h); } else throw e;\n}","preventionTips":["Do not pipeline batch MESSAGE packets before the CREATE BATCH response.","Keep the batch lifecycle on one connection."],"tags":["firebird","batch","statement-handle","protocol-ordering"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}