apache/seatunnel · error · OptionValidationException

'schema' must be configured when using a root-level 'query'

Error message

'schema' must be configured when using a root-level 'query'

What it means

Neo4jSourceFactory's root-level query validator requires a 'schema' block whenever a root-level 'query' is used in the Neo4j source config. Without an explicit schema, the connector cannot map the Cypher query result columns to SeaTunnel catalog columns (table name, columns, types). It throws OptionValidationException during option validation, before the job starts.

Solutions

  1. Add a root-level 'schema' block with table_name, columns (name/type pairs) matching the Cypher result.
  2. If you don't want a schema, switch to 'tables_configs' with per-entry query + schema instead of a root-level 'query'.
  3. Ensure the schema block is non-empty (an empty map still triggers the error).

Example fix

// before
source {
  Neo4j {
    uri = "bolt://localhost:7687"
    query = "MATCH (n:Person) RETURN n.name AS name, n.age AS age"
  }
}
// after
source {
  Neo4j {
    uri = "bolt://localhost:7687"
    query = "MATCH (n:Person) RETURN n.name AS name, n.age AS age"
    schema = {
      table = "person"
      columns = [
        { name = name, type = string }
        { name = age, type = int }
      ]
    }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

if (config.hasPath("query") && (!config.hasPath("schema") || config.getConfig("schema").isEmpty())) {
  throw new IllegalArgumentException("root-level 'query' requires a non-empty 'schema'");
}

Prevention

When it happens

Trigger: Configuring a Neo4j source with a root-level 'query' option (Cypher statement) while omitting the root-level 'schema' option, or supplying an empty schema map. evaluate(ReadonlyConfig, String) throws when config.getOptional(ConnectorCommonOptions.SCHEMA) is absent or empty.

Common situations: Users copy a query-based Neo4j source example but delete the schema section; users migrating from table_configs-style configs forget schema is mandatory with root-level query; auto-generated configs omit schema because the connector cannot infer it from Cypher.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/3eea933890b42653. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-neo4j/src/main/java/org/apache/seatunnel/connectors/seatunnel/neo4j/source/Neo4jSourceFactory.java:178

    private static Neo4jConnectorException configError(String message) {
        return new Neo4jConnectorException(SeaTunnelAPIErrorCode.CONFIG_VALIDATION_FAILED, message);
    }

    static class SingleTableConfigValidator implements ConditionExtension<String> {

        @Override
        public String description() {
            return "'schema' must be configured when using a root-level 'query'";
        }

        @Override
        public boolean evaluate(ReadonlyConfig config, String query)
                throws OptionValidationException {
            Map<String, Object> schema =
                    config.getOptional(ConnectorCommonOptions.SCHEMA).orElse(null);
            if (schema == null || schema.isEmpty()) {
                throw new OptionValidationException(
                        "'schema' must be configured when using a root-level 'query'");
            }
            return true;
        }
    }

    static class TableConfigsValidator implements ConditionExtension<List<Map<String, Object>>> {

        @Override
        public String description() {
            return "each 'tables_configs' entry must contain a non-blank 'query' and a schema with a unique 'table'";
        }

        @Override
        public boolean evaluate(ReadonlyConfig config, List<Map<String, Object>> entries)
                throws OptionValidationException {
            if (config.getOptional(ConnectorCommonOptions.SCHEMA).isPresent()) {
                throw new OptionValidationException(

View on GitHub (pinned to cf67b549a7)