apache/seatunnel · error · HugeGraphConnectorException

HugeGraphConnectorErrorCode.ILLEGAL_CONFIG_ARGUMENT

HugeGraphConnectorErrorCode.ILLEGAL_CONFIG_ARGUMENT

Error message

Mapping[%s/%s]: 'nullableKeys' and 'notNullableKeys' are mutually exclusive — set at most one.

What it means

Thrown by SchemaValidator.validateMappingConfig when a mapping declares both nullableKeys and notNullableKeys. These are opposite ways to control nullability of an auto-created label; with an explicit nullableKeys allow-list present, notNullableKeys is silently ignored, so setting both is ambiguous and rejected up front.

Solutions

  1. Remove the nullable_keys list and keep only not_nullable_keys
  2. Remove the not_nullable_keys list and keep only nullable_keys
  3. If keys overlap differently per label, split the mapping into separate mappings each using one style

Example fix

# before — both set
nullable_keys = ["age", "nickname"]
not_nullable_keys = ["name"]
# after — single style
not_nullable_keys = ["name"]
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: nullable and not-nullable keys must not both be set
if (!mapping.getNullableKeys().isEmpty() && !mapping.getNotNullableKeys().isEmpty()) {
    throw new IllegalArgumentException("Set at most one of nullableKeys / notNullableKeys");
}

Try / catch

try {
    job.execute();
} catch (HugeGraphConnectorException e) {
    if (HugeGraphConnectorErrorCode.ILLEGAL_CONFIG_ARGUMENT.equals(e.getErrorCode())
            && e.getMessage().contains("mutually exclusive")) {
        // fix the HOCON config: keep only one of nullable_keys / not_nullable_keys
    } else { throw e; }
}

Prevention

When it happens

Trigger: A Vertex/Edge mapping in the SeaTunnel HugeGraph sink config contains non-empty nullable_keys and non-empty not_nullable_keys lists at the same time; detected during validateConfigOnly or validateMapping.

Common situations: Merging configs from two sources that used different nullability styles; incrementally adding keys to both lists over time; copy-pasting a mapping and appending a not_nullable_keys section without removing nullable_keys.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-hugegraph/src/main/java/org/apache/seatunnel/connectors/seatunnel/hugegraph/utils/SchemaValidator.java:173

    private void validateMapping(MappingConfig mapping) {
        validateMappingConfig(mapping);
        if (mapping.getType() == LabelType.VERTEX) {
            validateVertexMapping(mapping);
        } else {
            validateEdgeMapping(mapping);
        }
    }

    private void validateMappingConfig(MappingConfig mapping) {
        E.checkNotNull(mapping.getType(), "type", "mapping");
        E.checkNotNull(mapping.getLabel(), "label", "mapping");

        // nullableKeys and notNullableKeys are two opposite ways to steer nullability of an
        // auto-created label. Setting both is ambiguous — notNullableKeys is silently ignored once
        // an explicit nullableKeys allow-list is present — so reject it up front instead.
        if (!mapping.getNullableKeys().isEmpty() && !mapping.getNotNullableKeys().isEmpty()) {
            throw new HugeGraphConnectorException(
                    HugeGraphConnectorErrorCode.ILLEGAL_CONFIG_ARGUMENT,
                    String.format(
                            "Mapping[%s/%s]: 'nullableKeys' and 'notNullableKeys' are mutually "
                                    + "exclusive — set at most one.",
                            mapping.getType(), mapping.getLabel()));
        }

        // `properties` (selected whitelist) and `ignored` (blacklist) are opposite ways to choose
        // the property set; setting both is ambiguous.
        if (!mapping.getProperties().isEmpty() && !mapping.getIgnored().isEmpty()) {
            throw new HugeGraphConnectorException(
                    HugeGraphConnectorErrorCode.ILLEGAL_CONFIG_ARGUMENT,
                    String.format(
                            "Mapping[%s/%s]: 'properties' (selected) and 'ignored' are mutually "
                                    + "exclusive — set at most one.",
                            mapping.getType(), mapping.getLabel()));
        }
        validateSourceFields(mapping, mapping.getIgnored(), "ignored");

View on GitHub (pinned to cf67b549a7)