apache/seatunnel · error · IllegalArgumentException

Invalid DECIMAL definition: {decimalTypeDefinition}

Error message

Invalid DECIMAL definition: {decimalTypeDefinition}

What it means

AbstractDorisTypeConverter.getPrecisionAndScale parses strings like `DECIMAL(p,s)` by stripping the wrapper and splitting on a comma; if the result does not have exactly 2 parts it throws IllegalArgumentException with the offending definition. It means the DECIMAL type string did not match the expected `DECIMAL(precision,scale)` shape.

Source

Thrown at seatunnel-connectors-v2/connector-doris/src/main/java/org/apache/seatunnel/connectors/doris/datatype/AbstractDorisTypeConverter.java:486

                builder.dataType(DORIS_DATETIMEV2_ARRAY);
                break;
            default:
                throw CommonError.convertToConnectorTypeError(
                        IDENTIFIER, elementType.getSqlType().name(), columnName);
        }
    }

    protected static int[] getPrecisionAndScale(String decimalTypeDefinition) {
        // Remove the "DECIMALV3" part and the parentheses
        decimalTypeDefinition = decimalTypeDefinition.toUpperCase(Locale.ROOT);
        String numericPart = decimalTypeDefinition.replace("DECIMALV3(", "").replace(")", "");
        numericPart = numericPart.replace("DECIMAL(", "").replace(")", "");

        // Split by comma to separate precision and scale
        String[] parts = numericPart.split(",");

        if (parts.length != 2) {
            throw new IllegalArgumentException(
                    "Invalid DECIMAL definition: " + decimalTypeDefinition);
        }

        // Parse precision and scale from the split parts
        int precision = Integer.parseInt(parts[0].trim());
        int scale = Integer.parseInt(parts[1].trim());

        // Return an array containing precision and scale
        return new int[] {precision, scale};
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Normalize the type string to the exact `DECIMAL(p,s)` form (with both precision and scale) before conversion
  2. Handle scale-less DECIMAL(P) by defaulting scale (commonly 0) before calling the converter
  3. Add handling for DECIMALV2/DECIMALV3 prefixes in the converter's strip step

Example fix

// before
converter.precisionAndScale("DECIMAL(10)");
// after
String def = "DECIMAL(10)";
if (!def.matches("(?i)DECIMAL\\s*\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\)")) def = def.replaceFirst("(?i)DECIMAL\\s*\\(\\s*(\\d+)\\s*\\)", "DECIMAL($1,0)");
converter.precisionAndScale(def); // DECIMAL(10,0)
Defensive patterns

Strategy: validation

Validate before calling

// validate DECIMAL string before conversion
if (!typeStr.matches("(?i)DECIMAL\\s*\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\)")) {
    throw new IllegalArgumentException("DECIMAL must be DECIMAL(p,s), got: " + typeStr);
}

Type guard

boolean isParameterizedDecimal(String t) {
    return t != null && t.matches("(?i)DECIMAL\\s*\\(\\s*\\d+\\s*,\\s*\\d+\\s*\\)");
}

Try / catch

try {
    SeaTunnelDataType<?> dt = converter.precisionAndScale(typeStr);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Invalid DECIMAL definition")) {
        // normalize: append default scale or strip DECIMALV2/V3 prefixes, then retry
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a type string such as "DECIMAL", "DECIMAL(10)", "DECIMALV3(10,2)" (if the prefix strip doesn't match), or "decimal(p, s) extra" into precisionAndScale/getPrecisionAndScale.

Common situations: Mapping Doris DECIMAL(P) (scale omitted) or unparameterized DECIMAL into SeaTunnel types; upstream schema metadata returning DECIMAL variants (DECIMALV2/V3) not normalized before parsing.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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