apache/seatunnel · error · Neo4jConnectorException

READER_OPERATION_FAILED

READER_OPERATION_FAILED

Error message

Failed to read Neo4j table '${tableId}'.

What it means

While reading a specific Neo4j table (executing its Cypher query via the driver), a RuntimeException occurred. readTable wraps it in Neo4jConnectorException with code READER_OPERATION_FAILED and includes the table id, preserving the original as cause. If tableId is null, the original exception propagates unchanged.

Source

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

            this.context.signalNoMoreElement();
        }
    }

    private void readTable(Collector<SeaTunnelRow> output, Neo4jSourceTableConfig tableConfig) {
        final Query query = new Query(tableConfig.getQuery());
        try {
            session.readTransaction(
                    tx -> {
                        final Result result = tx.run(query);
                        result.stream()
                                .forEach(row -> output.collect(convertRecord(row, tableConfig)));
                        return null;
                    });
        } catch (RuntimeException exception) {
            if (tableConfig.getTableId() == null) {
                throw exception;
            }
            throw new Neo4jConnectorException(
                    CommonErrorCodeDeprecated.READER_OPERATION_FAILED,
                    "Failed to read Neo4j table '" + tableConfig.getTableId() + "'.",
                    exception);
        }
    }

    static SeaTunnelRow convertRecord(Record record, Neo4jSourceTableConfig tableConfig) {
        SeaTunnelRowType rowType = tableConfig.getRowType();
        Object[] fields = new Object[rowType.getTotalFields()];
        for (int i = 0; i < rowType.getTotalFields(); i++) {
            String fieldName = rowType.getFieldName(i);
            SeaTunnelDataType<?> fieldType = rowType.getFieldType(i);
            Value value = record.get(fieldName);
            fields[i] = convertType(fieldType, value);
        }
        SeaTunnelRow seaTunnelRow = new SeaTunnelRow(fields);
        if (tableConfig.getTableId() != null) {
            seaTunnelRow.setTableId(tableConfig.getTableId());

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read the cause of the Neo4jConnectorException for the actual driver/Cypher error.
  2. Validate the Cypher query directly against the Neo4j server (browser/shell).
  3. Check Neo4j availability, credentials, and query timeouts; increase driver timeout or add pagination for large results.

Example fix

// before
query = "MATCH (n:Persn) RETURN n.name AS name"
// after
query = "MATCH (n:Person) RETURN n.name AS name"
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate queries up front:
tables_configs.forEach(c -> driver.session().run("EXPLAIN " + c.getQuery()).consume());

Try / catch

try {
  readTable(tableConfig);
} catch (Neo4jConnectorException e) {
  log.error("table={} failed: {}", tableConfig.getTableId(), e.getCause());
  throw e;
}

Prevention

When it happens

Trigger: internalPollNext -> readTable executes the table's query with executeRead(tx -> ...); any RuntimeException from the driver (query syntax error, connection loss, timeout) is wrapped with "Failed to read Neo4j table '<tableId>'."

Common situations: Invalid Cypher syntax in tables_configs/root query; Neo4j server restart or network partition mid-read; auth/permission errors executing the query; driver timeouts on large result sets.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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