apache/seatunnel · error · MongodbConnectorException

ILLEGAL_ARGUMENT

ILLEGAL_ARGUMENT

Error message

Unable to compare bson values between %s and %s

What it means

BsonUtils.compareBsonValue implements MongoDB's BSON comparison order but only covers the types it handles in its switch (numbers, strings, documents, arrays, timestamps, etc.). When both values fall through to the default branch — e.g. compared types are of different BSON categories or an unhandled type like BINARY/SYMBOL — it cannot produce an ordering and throws ILLEGAL_ARGUMENT.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-mongodb/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mongodb/utils/BsonUtils.java:103

                return compareBooleans(o1.asBoolean().getValue(), o2.asBoolean().getValue());
            case DATE_TIME:
                return compareDateTimes(o1.asDateTime().getValue(), o2.asDateTime().getValue());
            case TIMESTAMP:
                return compareTimestamps(o1.asTimestamp().getValue(), o2.asTimestamp().getValue());
            case BINARY:
                return compareBsonBinary(o1.asBinary(), o2.asBinary());
            case OBJECT_ID:
                return o1.asObjectId().compareTo(o2.asObjectId());
            case DOCUMENT:
            case DB_POINTER:
                return compareBsonDocument(toBsonDocument(o1), toBsonDocument(o2));
            case ARRAY:
                return compareBsonArray(o1.asArray(), o2.asArray());
            case JAVASCRIPT_WITH_SCOPE:
                return compareJavascriptWithScope(
                        o1.asJavaScriptWithScope(), o2.asJavaScriptWithScope());
            default:
                throw new MongodbConnectorException(
                        ILLEGAL_ARGUMENT,
                        String.format("Unable to compare bson values between %s and %s", o1, o2));
        }
    }

    private static int compareBsonValues(BsonValue v1, BsonValue v2) {
        return compareBsonValue(v1, v2, false);
    }

    private static int compareBsonNumbers(BsonNumber n1, BsonNumber n2) {
        Decimal128 decimal1 = getDecimal128FromCache(n1);
        Decimal128 decimal2 = getDecimal128FromCache(n2);
        return decimal1.compareTo(decimal2);
    }

    private static int compareStrings(String s1, String s2) {
        return getStringFromCache(s1).compareTo(getStringFromCache(s2));
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure the compared field(s) have a consistent BSON type across all documents (normalize the source data or the extraction logic)
  2. Extend compareBsonValue to handle the missing BsonType cases (add switch branches following MongoDB's type-order, e.g. via BsonUtils.typeOrder)
  3. Log the two BsonValues and their BsonTypes to identify which type pair is unhandled and normalize before comparison

Example fix

// before
throw new MongodbConnectorException(ILLEGAL_ARGUMENT,
    String.format("Unable to compare bson values between %s and %s", o1, o2));
// after (handle binary)
case BINARY:
    return o1.asBinary().getData().length != o2.asBinary().getData().length
        ? Integer.signum(o1.asBinary().getData().length - o2.asBinary().getData().length)
        : ByteBuffer.wrap(o1.asBinary().getData()).compareTo(ByteBuffer.wrap(o2.asBinary().getData()));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!bsonValue.isNumber() && !bsonValue.isString() && !bsonValue.isDocument()
    && !bsonValue.isArray() && !bsonValue.isDateTime() && !bsonValue.isTimestamp()) {
    // normalize or skip before comparison
}

Type guard

boolean comparable(BsonValue v) {
    BsonType t = v.getBsonType();
    return t == BsonType.DOUBLE || t == BsonType.INT32 || t == BsonType.INT64
        || t == BsonType.DECIMAL128 || t == BsonType.STRING || t == BsonType.DOCUMENT
        || t == BsonType.ARRAY || t == BsonType.DATE_TIME || t == BsonType.TIMESTAMP;
}

Try / catch

try {
    int cmp = BsonUtils.compareBsonValue(a, b);
} catch (MongodbConnectorException e) {
    log.warn("Uncomparable BSON types: {} vs {}", a.getBsonType(), b.getBsonType());
    // fall back to typeOrder comparison or skip the record
}

Prevention

When it happens

Trigger: compareBsonValue(o1, o2) invoked with BsonValues whose BsonType is not one of the handled cases (e.g. BINARY vs STRING, SYMBOL, UNHANDLED); recursively reached via compareBsonValues, compareBsonDocument (comparing field values of different types), compareBsonArray (mismatched element types), or smallestValueOfArray on arrays with heterogeneous element types.

Common situations: Incremental snapshot key comparison over a shard key or document field whose BSON type changed between documents (e.g. a field that was a string becomes binary); resume-token or split computation touching mixed-type arrays; data written by an older driver with legacy types (Symbol).

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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