apache/beam · error · IllegalArgumentException

typehint for arg type %s already exists

Error message

typehint for arg type %s already exists

What it means

PythonExternalTransform.withTypeHint stores a mapping from Java argument types to Beam Schema.FieldTypes so custom Java types can be converted for the Python side. The library throws IllegalArgumentException when you call withTypeHint twice for the same Java class, because storing two different field types for one argument type would be ambiguous. Each arg type may have exactly one type hint.

Source

Thrown at sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/PythonExternalTransform.java:248

    }
    this.providedKwargsRow = kwargs;
    return this;
  }

  /**
   * Specifies the field type of arguments.
   *
   * <p>Type hints are especially useful for logical types since type inference does not work well
   * for logical types.
   *
   * @param argType A class object for the argument type.
   * @param fieldType A schema field type for the argument.
   * @return updated wrapper for the cross-language transform.
   */
  public PythonExternalTransform<InputT, OutputT> withTypeHint(
      java.lang.Class<?> argType, Schema.FieldType fieldType) {
    if (typeHints.containsKey(argType)) {
      throw new IllegalArgumentException(
          String.format("typehint for arg type %s already exists", argType));
    }
    typeHints.put(argType, fieldType);
    return this;
  }

  /**
   * Specifies the keys and {@link Coder}s of the output {@link PCollection}s produced by this
   * transform.
   *
   * @param outputCoders a mapping from output keys to {@link Coder}s.
   * @return updated wrapper for the cross-language transform.
   */
  public PythonExternalTransform<InputT, OutputT> withOutputCoders(
      Map<String, Coder<?>> outputCoders) {
    if (this.outputCoders.size() > 0) {
      throw new IllegalArgumentException("Output coders were already specified");
    }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the duplicate withTypeHint call so each Java class is registered only once
  2. Track which classes already have hints (e.g. a Set in your config loop) and skip or overwrite before calling withTypeHint
  3. If overwrite is intended, rebuild a fresh PythonExternalTransform instead of reusing the configured one

Example fix

// before
transform.apply("step", PythonExternalTransform.<...>from("my.Mod")
    .withTypeHint(MyType.class, Schema.FieldType.STRING)
    .withTypeHint(MyType.class, Schema.FieldType.INT64));
// after
transform.apply("step", PythonExternalTransform.<...>from("my.Mod")
    .withTypeHint(MyType.class, Schema.FieldType.STRING));
Defensive patterns

Strategy: validation

Validate before calling

if (java.lang.reflect.Field f = null; true) {} // n/a — check the builder chain instead:
Set<Class<?>> hinted = new HashSet<>();
if (!hinted.add(argType)) { throw new IllegalStateException("duplicate type hint for " + argType); }
transform.withTypeHint(argType, fieldType);

Try / catch

try {
  transform.withTypeHint(argType, fieldType);
} catch (IllegalArgumentException e) {
  // duplicate hint: skip or rebuild transform
}

Prevention

When it happens

Trigger: Calling withTypeHint(argType, fieldType) when typeHints already contains an entry for the same argType class — typically by calling withTypeHint twice with the same class on the same builder, or reusing a builder that already had that hint registered.

Common situations: Builders that configure several arguments in a loop and call withTypeHint for the same class twice; copying configuration from an existing transform onto one that already has hints; accidental duplicate registration during fluent-builder chaining.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/2e8f637b6e219077. Report an issue: GitHub.