{"record":{"id":"516fc8a928faff62","repo":"apache/seatunnel","slug":"vitess-cdc-requires-resolved-catalog-tables-for-de","errorCode":null,"errorMessage":"Vitess CDC requires resolved catalog tables for deterministic table identity.","messagePattern":"Vitess CDC requires resolved catalog tables for deterministic table identity\\.","errorType":"validation","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":84,"sourceCode":"            ReadonlyConfig options,\n            List<CatalogTable> catalogTables,\n            StartupMode startupMode,\n            String specificStartupVgtid) {\n        this.options = options;\n        this.catalogTables = Collections.unmodifiableList(new ArrayList<>(catalogTables));\n        this.startupMode = startupMode;\n        this.specificStartupVgtid = specificStartupVgtid;\n    }\n\n    /**\n     * Builds the validated connector configuration.\n     *\n     * <p>Vitess does not expose database/schema names the same way as MySQL-based connectors, so\n     * 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            }","sourceCodeStart":66,"sourceCodeEnd":102,"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#L66-L102","documentation":"VitessSourceConfig.of requires a non-empty, pre-resolved list of CatalogTable objects because Vitess does not expose database/schema names the way MySQL-based connectors do; table identity must be deterministic before the source starts. An empty or null list means the source cannot establish which tables to read, so it fails fast.","triggerScenarios":"Calling VitessSourceConfig.of(options, catalogTables) with null or an empty catalogTables list — typically when upstream catalog/table resolution returned nothing, e.g. table-path patterns matched no tables or catalog discovery was skipped.","commonSituations":"Configuring table patterns that match zero tables in the keyspace; running through a code path that passes tables lazily instead of resolved CatalogTables; typos in table include lists so no catalog tables are produced.","solutions":["Fix the table include patterns/paths so at least one catalog table resolves","Ensure the catalog resolution step runs and returns CatalogTable objects before building VitessSourceConfig","Verify keyspace and table names against the live Vitess cluster (show tables in the keyspace)","Pass the explicit table list in config if automatic discovery yields nothing"],"exampleFix":"// before\nList<CatalogTable> tables = catalog.resolve(pattern); // returns []\nVitessSourceConfig.of(options, tables); // throws\n// after: validate before building\nif (tables == null || tables.isEmpty()) {\n    throw new IllegalArgumentException(\"No tables matched; check keyspace/table patterns\");\n}\nVitessSourceConfig.of(options, tables);","handlingStrategy":"validation","validationCode":"List<CatalogTable> tables = resolveCatalogTables(options);\nif (tables == null || tables.isEmpty()) {\n    throw new IllegalArgumentException(\"No catalog tables resolved; fix keyspace/table patterns before building VitessSourceConfig\");\n}\nVitessSourceConfig.of(options, tables);","typeGuard":"static boolean hasResolvedTables(List<CatalogTable> tables) {\n    return tables != null && !tables.isEmpty();\n}","tryCatchPattern":"try {\n    cfg = VitessSourceConfig.of(options, catalogTables);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"requires resolved catalog tables\")) {\n        LOG.error(\"Table patterns matched nothing; check keyspace and include lists\");\n    }\n    throw e;\n}","preventionTips":["Qualify table patterns with keyspace and verify matches against the live cluster","Resolve catalog tables synchronously before constructing the source config","Test table-include patterns in staging with the same keyspace"],"tags":["vitess","cdc","config","catalog-tables","empty-list"],"backgroundTag":"empty-required-field","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"}