apache/seatunnel · error · DorisConnectorException

SHOULD_NEVER_HAPPEN

SHOULD_NEVER_HAPPEN

Error message

never happen error.

What it means

DorisValueReader.next() is only valid when rows remain; calling it after the internal row batch is exhausted violates the reader contract, so it throws SHOULD_NEVER_HAPPEN. hasNext() returned false right before the call.

Source

Thrown at seatunnel-connectors-v2/connector-doris/src/main/java/org/apache/seatunnel/connectors/doris/source/reader/DorisValueReader.java:260

                    }
                }
                hasNext = !eos.get();
            } finally {
                clientLock.unlock();
            }
        }
        return hasNext;
    }

    /**
     * get next value.
     *
     * @return next value
     */
    public SeaTunnelRow next() {
        if (!hasNext()) {
            log.error(SHOULD_NOT_HAPPEN_MESSAGE);
            throw new DorisConnectorException(
                    DorisConnectorErrorCode.SHOULD_NEVER_HAPPEN, "never happen error.");
        }
        SeaTunnelRow next = rowBatch.next();
        next.setTableId(dorisSourceTable.getTablePath().toString());
        return next;
    }

    public void close() {
        clientLock.lock();
        try {
            TScanCloseParams closeParams = new TScanCloseParams();
            closeParams.setContextId(contextId);
            client.closeScanner(closeParams);
        } catch (Exception e) {
            log.error("Failed to close reader with context id {}", contextId, e);
            throw new DorisConnectorException(DorisConnectorErrorCode.RESOURCE_CLOSE_FAILED, e);
        } finally {
            clientLock.unlock();

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Guard every next() call with hasNext()
  2. If it occurs inside stock code, file a bug with the split/partition info and full stacktrace
  3. Check whether the partition produced an empty/failed read that skipped refill logic
  4. Pin to a fixed connector version if this is a known regression

Example fix

// before
while (true) { row = valueReader.next(); ... }
// after
while (valueReader.hasNext()) { row = valueReader.next(); ... }
Defensive patterns

Strategy: type-guard

Validate before calling

if (valueReader.hasNext()) { row = valueReader.next(); }

Type guard

boolean safe = valueReader != null && valueReader.hasNext();

Try / catch

try { row = valueReader.next(); } catch (DorisConnectorException e) { if (e.getMessage().contains("never happen")) { LOG.error("exhausted reader; report bug with partition info"); } throw e; }

Prevention

When it happens

Trigger: next() invoked when hasNext() is false — e.g. caller keeps calling next() past the end of a partition's rows or after a exhausted rowBatch refill failure.

Common situations: Custom/patched reader loop ignoring hasNext(); race where the underlying Doris reader exhausted early due to empty partitions; connector bug in batch boundary handling.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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