{"record":{"id":"06bfc1d19dc5edbe","repo":"apache/seatunnel","slug":"vitess-cdc-captures-one-keyspace-per-source-table","errorCode":null,"errorMessage":"Vitess CDC captures one keyspace per source. Table '%s' does not belong to keyspace '%s'.","messagePattern":"Vitess CDC captures one keyspace per source\\. Table '(.+?)' does not belong to keyspace '(.+?)'\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-vitess/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/vitess/config/VitessSourceConfig.java","lineNumber":98,"sourceCode":"     * table paths must already be deterministic before the source starts.\n     */\n    public static VitessSourceConfig of(ReadonlyConfig options, List<CatalogTable> catalogTables) {\n        if (catalogTables == null || catalogTables.isEmpty()) {\n            throw new IllegalArgumentException(\n                    \"Vitess CDC requires resolved catalog tables for deterministic table identity.\");\n        }\n\n        String keyspace = options.get(VitessSourceOptions.KEYSPACE);\n        for (CatalogTable catalogTable : catalogTables) {\n            String databaseName = catalogTable.getTablePath().getDatabaseName();\n            if (databaseName == null) {\n                throw new IllegalArgumentException(\n                        String.format(\n                                \"Vitess CDC requires database-qualified table paths, but table '%s' does not define a database name.\",\n                                catalogTable.getTablePath()));\n            }\n            if (!keyspace.equals(databaseName)) {\n                throw new IllegalArgumentException(\n                        String.format(\n                                \"Vitess CDC captures one keyspace per source. Table '%s' does not belong to keyspace '%s'.\",\n                                catalogTable.getTablePath(), keyspace));\n            }\n            if (catalogTable.getTablePath().getSchemaName() != null) {\n                throw new IllegalArgumentException(\n                        String.format(\n                                \"Vitess CDC does not support schema-qualified table paths. Table '%s' contains an unexpected schema component.\",\n                                catalogTable.getTablePath()));\n            }\n        }\n\n        StartupMode startupMode = options.get(VitessSourceOptions.STARTUP_MODE);\n        String specificVgtid =\n                options.getOptional(VitessSourceOptions.STARTUP_SPECIFIC_OFFSET_VGTID).orElse(null);\n        if (startupMode == StartupMode.SPECIFIC) {\n            if (specificVgtid == null) {\n                throw new IllegalArgumentException(","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-vitess/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/vitess/config/VitessSourceConfig.java#L80-L116","documentation":"This IllegalArgumentException is thrown during Vitess CDC source configuration validation when a table path's database (keyspace) portion does not match the keyspace configured for the source. Vitess CDC captures change streams for exactly one keyspace per source instance, so all declared tables must belong to that keyspace.","triggerScenarios":"Calling VitessSourceConfig.of (directly or via the Vitess source factory) with a tables list where a CatalogTable's table path resolves to a databaseName different from the configured keyspace option.","commonSituations":"Copy-pasting table configs from a multi-keyspace job into a single-keyspace source; typos in the keyspace option; renaming a keyspace in Vitess but not updating the table paths; mixing tables from shard-merged keyspaces like 'commerce' and 'customer' in one source.","solutions":["Align the table's database name with the configured keyspace option, e.g. change table path to keyspace.table","Change the keyspace option to match the tables you actually declared","Split into multiple Vitess CDC sources, one per keyspace"],"exampleFix":"// before\ntables = [\"commerce.orders\", \"customer.users\"] with keyspace = \"commerce\"\n// after\ntables = [\"commerce.orders\", \"commerce.users\"] with keyspace = \"commerce\"","handlingStrategy":"validation","validationCode":"String keyspace = options.get(VitessSourceOptions.KEYSPACE);\nfor (String table : tables) {\n    if (!table.startsWith(keyspace + \".\")) {\n        throw new IllegalArgumentException(\"table \" + table + \" not in keyspace \" + keyspace);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { VitessSourceConfig.of(catalogTables, options); } catch (IllegalArgumentException e) { /* fix keyspace/table mismatch before resubmitting */ }","preventionTips":["Generate table paths programmatically from the keyspace option so they always agree","One Vitess CDC source per keyspace","Lint configs for keyspace.table consistency before submit"],"tags":["cdc","vitess","config-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}