{"record":{"id":"990b31b49a1e788f","repo":"apache/seatunnel","slug":"tables-configs-d-schema-must-be-configured-an","errorCode":null,"errorMessage":"tables_configs[%d]: 'schema' must be configured and non-empty","messagePattern":"tables_configs\\[(.+?)\\]: 'schema' must be configured and non-empty","errorType":"validation","errorClass":"OptionValidationException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-neo4j/src/main/java/org/apache/seatunnel/connectors/seatunnel/neo4j/source/Neo4jSourceFactory.java","lineNumber":211,"sourceCode":"        public boolean evaluate(ReadonlyConfig config, List<Map<String, Object>> entries)\n                throws OptionValidationException {\n            if (config.getOptional(ConnectorCommonOptions.SCHEMA).isPresent()) {\n                throw new OptionValidationException(\n                        \"root-level 'schema' cannot be used with 'tables_configs'\");\n            }\n\n            Set<String> tableIds = new HashSet<>();\n            for (int i = 0; i < entries.size(); i++) {\n                Map<String, Object> entry = entries.get(i);\n                Object query = entry.get(Neo4jSourceOptions.KEY_QUERY.key());\n                if (!(query instanceof String) || ((String) query).trim().isEmpty()) {\n                    throw new OptionValidationException(\n                            \"tables_configs[%d]: 'query' must be configured and non-blank\", i);\n                }\n\n                Object schemaValue = entry.get(ConnectorCommonOptions.SCHEMA.key());\n                if (!(schemaValue instanceof Map) || ((Map<?, ?>) schemaValue).isEmpty()) {\n                    throw new OptionValidationException(\n                            \"tables_configs[%d]: 'schema' must be configured and non-empty\", i);\n                }\n\n                Object tableValue =\n                        ((Map<?, ?>) schemaValue).get(ConnectorCommonOptions.TABLE.key());\n                if (!(tableValue instanceof String) || ((String) tableValue).trim().isEmpty()) {\n                    throw new OptionValidationException(\n                            \"tables_configs[%d]: 'schema.table' must be configured and non-blank\",\n                            i);\n                }\n\n                String tableId = ((String) tableValue).trim();\n                if (!tableIds.add(tableId)) {\n                    throw new OptionValidationException(\n                            \"tables_configs[%d]: duplicate 'schema.table' value '%s'\", i, tableId);\n                }\n            }\n            return true;","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-neo4j/src/main/java/org/apache/seatunnel/connectors/seatunnel/neo4j/source/Neo4jSourceFactory.java#L193-L229","documentation":"Every tables_configs entry must define a non-empty 'schema' map so the connector can map the entry's Cypher result to a SeaTunnel table. If the entry's schema is missing, not a Map, or an empty Map, the factory throws OptionValidationException with the entry's index.","triggerScenarios":"tables_configs[i] lacking a 'schema' key, or schema present but empty ({}), detected via !(schemaValue instanceof Map) || ((Map) schemaValue).isEmpty().","commonSituations":"Users assume schema can be inherited from the root-level config (which is in fact rejected); copied examples omit schema; the schema block was accidentally nested at the wrong indentation level.","solutions":["Add a 'schema' block with table and columns to the tables_configs entry at the reported index.","Ensure the schema map contains at least table and columns definitions.","Verify YAML/HOCON indentation so schema is nested inside the entry, not a sibling."],"exampleFix":"// before\ntables_configs = [\n  { query = \"MATCH (n:Person) RETURN n.name AS name\" }\n]\n// after\ntables_configs = [\n  {\n    query = \"MATCH (n:Person) RETURN n.name AS name\"\n    schema = {\n      table = \"person\"\n      columns = [{ name = name, type = string }]\n    }\n  }\n]","handlingStrategy":"validation","validationCode":"tables_configs.eachWithIndex { entry, i ->\n  if (!(entry.schema instanceof Map) || entry.schema.isEmpty()) {\n    throw new IllegalArgumentException(\"tables_configs[${i}].schema must be a non-empty map\")\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Every entry must carry its own schema; do not rely on root-level inheritance.","Include both table and columns in each schema block.","Verify indentation when writing nested HOCON/YAML."],"tags":["neo4j","config-validation","missing-schema"],"backgroundTag":"missing-required-config-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}