{"record":{"id":"e4e155405729a628","repo":"apache/seatunnel","slug":"location-source-configindex-factoryid-did-no","errorCode":null,"errorMessage":"${location(SOURCE, configIndex, factoryId)} did not infer any source schema.","messagePattern":"(.+?) did not infer any source schema\\.","errorType":"validation","errorClass":"ConfigCheckException","httpStatus":null,"severity":"error","filePath":"seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/command/DryRunConnectValidator.java","lineNumber":160,"sourceCode":"            int configIndex,\n            Config sourceConfig,\n            ClassLoader classLoader,\n            LinkedHashMap<String, SchemaInfo> tableWithSchemas,\n            List<PluginResult> results) {\n        ReadonlyConfig readonlyConfig = ReadonlyConfig.fromConfig(sourceConfig);\n        String factoryId = ConfigParserUtil.getFactoryId(readonlyConfig);\n        String outputId = readonlyConfig.getOptional(PLUGIN_OUTPUT).orElse(DEFAULT_ID);\n        try {\n            TableSourceFactory factory =\n                    FactoryUtil.discoverFactory(classLoader, TableSourceFactory.class, factoryId);\n            TableSourceFactoryContext context =\n                    new TableSourceFactoryContext(readonlyConfig, classLoader);\n\n            if (factory instanceof SupportSourceDryRunValidation) {\n                SupportSourceDryRunValidation validation = (SupportSourceDryRunValidation) factory;\n                List<CatalogTable> catalogTables = validation.inferSchemaForDryRun(context);\n                if (catalogTables == null || catalogTables.isEmpty()) {\n                    throw new ConfigCheckException(\n                            location(PluginType.SOURCE, configIndex, factoryId)\n                                    + \" did not infer any source schema.\");\n                }\n                validation.validateConnectionForDryRun(context, catalogTables);\n                tableWithSchemas.put(outputId, SchemaInfo.trusted(catalogTables));\n                results.add(\n                        PluginResult.validated(\n                                PluginType.SOURCE,\n                                configIndex,\n                                factoryId,\n                                \"schema inferred and connection validated\"));\n                return;\n            }\n\n            if (hasExplicitSchema(readonlyConfig)) {\n                // Schema comes from the user's config, so downstream schema checks stay\n                // meaningful even though the connector itself was not contacted.\n                List<CatalogTable> catalogTables = factory.discoverTableSchemas(context);","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/command/DryRunConnectValidator.java#L142-L178","documentation":"During dry-run CONNECT validation, DryRunConnectValidator.validateSource calls inferSchemaForDryRun on factories implementing SupportSourceDryRunValidation. If the factory returns null or an empty list of CatalogTable, a ConfigCheckException is thrown saying the source inferred no schema. It ensures every source produces at least one table schema before the DAG is validated.","triggerScenarios":"Running with --dry-run CONNECT on a config whose source connector supports dry-run validation but cannot infer a schema for the given options — e.g. a query/table that resolves to nothing, empty catalog/database settings, or a connector whose dry-run implementation returns no tables for the supplied readonlyConfig.","commonSituations":"Typos in table/database names; source connector returning no columns for the requested query; connector dry-run implementation not supporting the option combination (e.g. a format or query mode the schema inference path ignores).","solutions":["Verify the source's table/catalog/database options point at an existing object that has columns.","Run the source without dry-run to see if it works normally; if it does, this may be a connector dry-run limitation — report/upgrade the connector.","Check connector documentation for required options for schema inference (e.g. query vs table)."],"exampleFix":"// before\nsource {\n  Jdbc {\n    url = \"jdbc:mysql://localhost:3306\"\n    query = \"\"\n  }\n}\n// after\nsource {\n  Jdbc {\n    url = \"jdbc:mysql://localhost:3306/db\"\n    query = \"select id, name from users\"\n  }\n}","handlingStrategy":"validation","validationCode":"// verify the source object exists and has columns before dry-run\n// e.g. for JDBC: run `DESCRIBE <table>` or `SELECT ... LIMIT 1` with the same credentials","typeGuard":null,"tryCatchPattern":"try { validateConf(conf, DryRun.CONNECT); } catch (ConfigCheckException e) { if (e.getMessage().endsWith(\"did not infer any source schema.\")) { fixSourceSchemaOptions(conf); } else { throw e; } }","preventionTips":["Ensure table/query options resolve to an existing object with columns","Keep connector options (database, schema, table) fully qualified and typo-free","Test schema inference with a minimal config before scaling up","Check the connector's docs for options required by schema inference"],"tags":["dry-run","schema-inference","source","config-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}