apache/beam · error · RuntimeException

Unable to generate a creator for {} with schema {}

Error message

Unable to generate a creator for {} with schema {}

What it means

createConstructorCreator generates a schema-compatible creator that calls clazz.getDeclaredConstructor().newInstance(). If reflective instantiation fails (abstract class, no no-arg constructor, inaccessible constructor, constructor throwing), it throws this RuntimeException with the class and schema in the message. Unlike error 383 the cause is also swallowed here (no `e` passed).

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/utils/POJOUtils.java:231

              .method(ElementMatchers.named("create"))
              .intercept(
                  new ConstructorCreateInstruction(
                      types, clazz, constructor, typeConversionsFactory));

      return builder
          .visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES))
          .make()
          .load(
              ReflectHelpers.findClassLoader(clazz.getClassLoader()),
              getClassLoadingStrategy(clazz))
          .getLoaded()
          .getDeclaredConstructor()
          .newInstance();
    } catch (InstantiationException
        | IllegalAccessException
        | NoSuchMethodException
        | InvocationTargetException e) {
      throw new RuntimeException(
          "Unable to generate a creator for " + clazz + " with schema " + schema);
    }
  }

  public static SchemaUserTypeCreator getStaticCreator(
      TypeDescriptor<?> typeDescriptor,
      Method creator,
      Schema schema,
      FieldValueTypeSupplier fieldValueTypeSupplier,
      TypeConversionsFactory typeConversionsFactory) {
    return CACHED_CREATORS.computeIfAbsent(
        TypeDescriptorWithSchema.create(typeDescriptor, schema),
        c -> {
          List<FieldValueTypeInformation> types =
              fieldValueTypeSupplier.get(typeDescriptor, schema);
          return createStaticCreator(
              typeDescriptor.getRawType(), creator, schema, types, typeConversionsFactory);
        });

View on GitHub (pinned to 12126d8942)

Solutions

  1. Add a public zero-argument constructor to the class.
  2. Annotate an appropriate constructor or static method with @SchemaCreate so Beam does not use the default constructor path.
  3. Make the nested class static and public; widen the constructor's visibility.
  4. Debug the root cause by temporarily invoking clazz.getDeclaredConstructor().newInstance() yourself to see the real reflective exception.

Example fix

// before
public class Point {
  private Point() {} // private no-arg ctor
  public static Point of(int x, int y) {...}
}
// after
public class Point {
  @SchemaCreate
  public static Point create(int x, int y) { return new Point(x, y); }
}
Defensive patterns

Strategy: validation

Validate before calling

try {
  clazz.getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
  throw new IllegalStateException(clazz + " is not reflectively instantiable: " + e);
}

Try / catch

try {
  SchemaUserTypeCreator creator = POJOUtils.getCreator(typeDescriptor, schema, factory);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Unable to generate a creator for")) {
    // add a no-arg constructor or @SchemaCreate and redeploy
  } else throw e;
}

Prevention

When it happens

Trigger: Calling createConstructorCreator (via getCreator) for a type without an accessible zero-argument constructor, an abstract class or interface, a non-public constructor, or a constructor that throws at instantiation time.

Common situations: Non-static inner classes, Kotlin/data classes without a no-arg constructor, private default constructors, or builder-only classes being handed to schema inference.

Related errors


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