apache/beam · error · IllegalArgumentException
ChangeStreamName can't be empty
Error message
ChangeStreamName can't be empty
What it means
In buildExternal() for the Spanner change-stream reader, after checkMandatoryFields() the configuration's changeStreamName is checked and this IllegalArgumentException is thrown when it is empty. Reading a Cloud Spanner change stream requires the exact name of an existing change stream, so an empty name cannot be dispatched to the Spanner API.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java:499
}
}
public void setWatermarkRefreshRate(@Nullable String watermarkRefreshRateString) {
if (watermarkRefreshRateString != null) {
this.watermarkRefreshRate = Duration.parse(watermarkRefreshRateString);
}
}
}
@Override
@NonNull
public PTransform<PBegin, PCollection<String>> buildExternal(
ChangeStreamReaderBuilder.Configuration configuration) {
configuration.checkMandatoryFields();
if (configuration.changeStreamName.isEmpty()) {
throw new IllegalArgumentException("ChangeStreamName can't be empty");
}
if (configuration.metadataInstance.isEmpty()) {
throw new IllegalArgumentException("MetadataInstance can't be empty");
}
if (configuration.metadataDatabase.isEmpty()) {
throw new IllegalArgumentException("MetadataDatabase can't be empty");
}
SpannerIO.ReadChangeStream readChangeStream =
SpannerIO.readChangeStream()
.withProjectId(configuration.projectId)
.withInstanceId(configuration.instanceId)
.withDatabaseId(configuration.databaseId)
.withChangeStreamName(configuration.changeStreamName)
.withMetadataInstance(configuration.metadataInstance)
.withMetadataDatabase(configuration.metadataDatabase);View on GitHub (pinned to 12126d8942)
Solutions
- Set the change stream name in the configuration (non-empty), matching `gcloud spanner change-streams list` output.
- Verify any templated value (env var/parameter substitution) actually resolved to a non-empty string.
- Add a pre-build validation that changeStreamName is non-null and non-empty.
Example fix
// before
{"changeStreamName": "", "metadataInstance": "meta-i"}
// after
{"changeStreamName": "my-stream", "metadataInstance": "meta-i"} Defensive patterns
Strategy: validation
Validate before calling
if (changeStreamName == null || changeStreamName.isEmpty()) { throw new IllegalArgumentException("changeStreamName must be provided to read a change stream"); } Try / catch
try { external.buildExternal(config); } catch (IllegalArgumentException e) { throw new ConfigException("Change stream config incomplete: " + e.getMessage(), e); } Prevention
- Verify change stream names with gcloud spanner change-streams list before submitting the pipeline.
- Assert template variables resolved to non-empty values before building external transforms.
- Keep change stream config fields required (non-optional) in your pipeline-spec schema.
When it happens
Trigger: Building the ChangeStreamReader external transform with configuration.changeStreamName empty or unset — e.g. a pipeline spec where the changeStreamName key is missing, blank, or the value failed to interpolate.
Common situations: Hand-written JSON/YAML pipeline templates missing the change stream name; templating engines leaving ${CHANGE_STREAM} unexpanded or empty; users confusing the change stream name with the table name.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- databaseId can't be empty
- instanceId can't be empty
- Both clientCertPath and clientCertKeyPath must be specified
- Query and table params are mutually exclusive. Set just one
- Schema can't be empty
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/e322bea3e3e642e9.
Report an issue: GitHub.