pentaho/pentaho-kettle · error · KettleException

AvroInput.Error.UnionError2

Error message

AvroInput.Error.UnionError2

What it means

Kettle exception thrown by checkUnion when a two-type union does not include NULL. The reader expects nullable unions ['null', X]; a union of two non-null types (e.g. ['int','string']) has no null branch and cannot be processed.

Solutions

  1. Change the union to include a null branch: ["null", <type>], typically with null as the default branch.
  2. Pick one concrete type and remove the union if both branches are non-null.
  3. Normalize the schema upstream (schema resolution/evolution step) before Pentaho reads it.
  4. Verify the configured path targets the right field; a neighboring field may actually be the nullable one.

Example fix

// before
{"name":"v","type":["int","long"]}
// after
{"name":"v","type":["null","long"],"default":null}
Defensive patterns

Strategy: validation

Validate before calling

// Require a NULL branch in any union before reading
List<Schema> types = fieldSchema.getTypes();
if (types.size() == 2 && types.stream().noneMatch(t -> t.getType() == Schema.Type.NULL)) {
  throw new IllegalArgumentException("Union ['" + types.get(0) + "','" + types.get(1) + "'] lacks a null branch");
}

Try / catch

try {
  value = reader.convertToKettleValue(record, schema, field);
} catch (KettleException e) {
  if (e.getMessage().contains("UnionError2")) {
    logError("Union has no null branch — add 'null' to the union in the schema", e);
  }
}

Prevention

When it happens

Trigger: checkUnion iterates union branches looking for Schema.Type.NULL; no branch is NULL so the 'ok' flag remains false and the exception is thrown (the non-null branch is returned otherwise).

Common situations: Files written with non-nullable two-way unions; schema regenerated without the null default; data producers that avoid Avro null-default convention; Kafka Avro records with ["int","long"] style unions.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/4d527f8285b0723b. Report an issue: GitHub.

Appendix: source

Thrown at plugins/avro-format/core/src/main/java/org/pentaho/di/trans/steps/avro/input/AvroNestedReader.java:870

    List<Schema> types = s.getTypes();

    // the type other than null
    Schema otherSchema = null;

    if ( types.size() != 2 ) {
      throw new KettleException( BaseMessages.getString( PKG, "AvroInput.Error.UnionError1" ) );
    }

    for ( Schema p : types ) {
      if ( p.getType() == Schema.Type.NULL ) {
        ok = true;
      } else {
        otherSchema = p;
      }
    }

    if ( !ok ) {
      throw new KettleException( BaseMessages.getString( PKG, "AvroInput.Error.UnionError2" ) );
    }

    return otherSchema;
  }

  /**
   * Cleanses a string path by ensuring that any variables names present in the path do not contain "."s (replaces any
   * dots with underscores).
   *
   * @param path the path to cleanse
   * @return the cleansed path
   */
  public static String cleansePath( String path ) {
    // look for variables and convert any "." to "_"

    int index = path.indexOf( "${" );

    int endIndex = 0;

View on GitHub (pinned to f3058517a1)