apache/beam · error · java.lang.RuntimeException
Failed to build transform from spec %s: %s
Error message
Failed to build transform from spec %s: %s
What it means
For schema-based (external configuration) transforms, ExpansionService.getTransform() parses the spec payload into a config object via transformBuilder.buildExternal(payloadToConfig(...)); any failure is rethrown as this RuntimeException with the spec and original message. It indicates the external config could not be parsed or the builder rejected it.
Source
Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/ExpansionService.java:337
}
private static class TransformProviderForBuilder implements TransformProvider {
private final ExternalTransformBuilder transformBuilder;
private TransformProviderForBuilder(ExternalTransformBuilder transformBuilder) {
this.transformBuilder = transformBuilder;
}
@Override
public PTransform getTransform(RunnerApi.FunctionSpec spec, PipelineOptions options) {
try {
Class configClass = getConfigClass(transformBuilder);
return transformBuilder.buildExternal(
payloadToConfig(
ExternalConfigurationPayload.parseFrom(spec.getPayload()), configClass));
} catch (Exception e) {
throw new RuntimeException(
String.format("Failed to build transform from spec %s: %s", spec, e.getMessage()), e);
}
}
@Override
public List<String> getDependencies(RunnerApi.FunctionSpec spec, PipelineOptions options) {
try {
Class configClass = getConfigClass(transformBuilder);
Optional<List<String>> dependencies =
transformBuilder.getDependencies(
payloadToConfig(
ExternalConfigurationPayload.parseFrom(spec.getPayload()), configClass),
options);
return dependencies.orElseGet(() -> TransformProvider.super.getDependencies(spec, options));
} catch (Exception e) {
throw new RuntimeException(
String.format("Failed to get dependencies for spec %s", spec), e);
}View on GitHub (pinned to 12126d8942)
Solutions
- Inspect the 'Caused by' to see whether parsing or buildExternal failed
- Compare the payload schema against the Java configuration class's registered schema
- Update the calling side to send exactly the fields the config class declares
- Rebuild/redeploy the expansion service if the config class changed recently
Example fix
// before: external payload with unexpected field type
{'retries': 'three'}
// after
{'retries': 3} Defensive patterns
Strategy: validation
Validate before calling
// validate payload fields against the Java config class schema before expansion
Schema configSchema = SchemaRegistry.createDefault().getSchema(ConfigClass.class);
if (!configSchema.getFieldNames().equals(sentFieldNames)) throw new IllegalArgumentException("payload schema mismatch"); Try / catch
try { transform = service.getTransform(spec, options); } catch (RuntimeException e) { if (e.getMessage().startsWith("Failed to build transform from spec")) { /* reconcile payload schema with config class */ } throw e; } Prevention
- Send only fields the Java config class declares, with matching types
- Register schemas for config classes with @DefaultSchema
- Test cross-language expansion in CI after any schema change
When it happens
Trigger: Calling getTransform on a FunctionSpec handled by a schema-based transform builder where ExternalConfigurationPayload parsing or payloadToConfig conversion throws (wrong schema, missing fields, reflective construction failure).
Common situations: Cross-language pipeline sending config values that do not match the Java config class schema; extra/missing parameters in the external payload; type mismatches (string vs int) after schema evolution.
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
- Schema in expansion request payload is not assignable to the
- Unable to generate coder for schema {schema}
- Expecting exactly one field, found
- The input schema must have exactly one field of type byte.
- Cannot merge schemas with different numbers of fields. schem
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/daef33e9d01788f0.
Report an issue: GitHub.