{"record":{"id":"4d9a5a5767eb9a4a","repo":"apache/seatunnel","slug":"document-routing-requires-whole-file-splits-but-g-4d9a5a","errorCode":null,"errorMessage":"Document routing requires whole-file splits, but got split ${split.splitId()}","messagePattern":"Document routing requires whole-file splits, but got split (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/split/MultipleTableFileSourceSplitEnumerator.java","lineNumber":242,"sourceCode":"                + \",...(\"\n                + (splits.size() - LOG_SPLIT_ID_LIMIT)\n                + \" more)\";\n    }\n\n    private int getSplitOwner(FileSourceSplit split, int assignCount, int numReaders) {\n        if (documentRoutingTableIds.contains(split.getTableId())) {\n            return getDocumentRouteOwner(split, numReaders);\n        }\n        return getRoundRobinSplitOwner(assignCount, numReaders);\n    }\n\n    private static int getRoundRobinSplitOwner(int assignCount, int numReaders) {\n        return assignCount % numReaders;\n    }\n\n    private static int getDocumentRouteOwner(FileSourceSplit split, int numReaders) {\n        if (split.getStart() != 0L || split.getLength() >= 0L) {\n            throw new IllegalStateException(\n                    \"Document routing requires whole-file splits, but got split \"\n                            + split.splitId());\n        }\n        String documentId = FileSourceDocumentRouting.buildDocumentId(split.getFilePath());\n        return FileSourceDocumentRouting.routeBucket(documentId, numReaders);\n    }\n\n    @Override\n    public void run() throws Exception {\n        for (int i = 0; i < context.currentParallelism(); i++) {\n            log.info(\"Assigned splits to reader [{}]\", i);\n            synchronized (lock) {\n                assignSplit(i);\n            }\n        }\n    }\n\n    @Override","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/split/MultipleTableFileSourceSplitEnumerator.java#L224-L260","documentation":"Same whole-file invariant as the base enumerator: with document routing enabled, splits must be whole-file (start=0, length<0) because routing buckets documents, not chunks. The multiple-table split enumerator's getDocumentRouteOwner throws IllegalStateException if a partial split arrives.","triggerScenarios":"Multi-table file source with document routing enabled, but splits were chunked (enable_file_split=true or a splitting strategy active); getSplitOwner delegates to getDocumentRouteOwner and the start/length check fails for the given split id.","commonSituations":"Mixed config where one table enabled file split; upgrade changed default splitting behavior; copying single-table split config into a routing-enabled multi-table job.","solutions":["Disable file splitting in all tables when document routing is enabled.","Disable document routing if chunk-level parallel assignment is the goal.","Make the enumerator produce whole-file splits (start=0, length=-1) for routing mode.","Audit each table block for enable_file_split/file_split_size settings."],"exampleFix":"// before\ntable1 { enable_file_split = true }\ndocument_routing = true\n// after\ntable1 { enable_file_split = false }\ndocument_routing = true","handlingStrategy":"try-catch","validationCode":"if (documentRoutingEnabled) require(split.getStart() == 0L && split.getLength() < 0L, \"document routing needs whole-file splits\");","typeGuard":"boolean isWholeFileSplit(FileSourceSplit s) { return s.getStart() == 0L && s.getLength() < 0L; }","tryCatchPattern":"try { owner = assigner.getSplitOwner(split, readers); } catch (IllegalStateException e) { log.error(\"Whole-file split required for document routing, got: {}\", e.getMessage()); throw e; }","preventionTips":["Disable file splitting in every table when routing is enabled in multi-table mode.","Audit all table blocks for enable_file_split before enabling document routing.","Make the enumerator's split generation agree with routing requirements.","Add a pre-assignment assert on split start/length for routing jobs."],"tags":["file-connector","multi-table","document-routing","split-assignment"],"backgroundTag":"internal-invariant-violation","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}