{"record":{"id":"e322bea3e3e642e9","repo":"apache/beam","slug":"changestreamname-can-t-be-empty","errorCode":null,"errorMessage":"ChangeStreamName can't be empty","messagePattern":"ChangeStreamName can't be empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java","lineNumber":499,"sourceCode":"        }\n      }\n\n      public void setWatermarkRefreshRate(@Nullable String watermarkRefreshRateString) {\n        if (watermarkRefreshRateString != null) {\n          this.watermarkRefreshRate = Duration.parse(watermarkRefreshRateString);\n        }\n      }\n    }\n\n    @Override\n    @NonNull\n    public PTransform<PBegin, PCollection<String>> buildExternal(\n        ChangeStreamReaderBuilder.Configuration configuration) {\n\n      configuration.checkMandatoryFields();\n\n      if (configuration.changeStreamName.isEmpty()) {\n        throw new IllegalArgumentException(\"ChangeStreamName can't be empty\");\n      }\n\n      if (configuration.metadataInstance.isEmpty()) {\n        throw new IllegalArgumentException(\"MetadataInstance can't be empty\");\n      }\n\n      if (configuration.metadataDatabase.isEmpty()) {\n        throw new IllegalArgumentException(\"MetadataDatabase can't be empty\");\n      }\n\n      SpannerIO.ReadChangeStream readChangeStream =\n          SpannerIO.readChangeStream()\n              .withProjectId(configuration.projectId)\n              .withInstanceId(configuration.instanceId)\n              .withDatabaseId(configuration.databaseId)\n              .withChangeStreamName(configuration.changeStreamName)\n              .withMetadataInstance(configuration.metadataInstance)\n              .withMetadataDatabase(configuration.metadataDatabase);","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerTransformRegistrar.java#L481-L517","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n{\"changeStreamName\": \"\", \"metadataInstance\": \"meta-i\"}\n// after\n{\"changeStreamName\": \"my-stream\", \"metadataInstance\": \"meta-i\"}","handlingStrategy":"validation","validationCode":"if (changeStreamName == null || changeStreamName.isEmpty()) { throw new IllegalArgumentException(\"changeStreamName must be provided to read a change stream\"); }","typeGuard":null,"tryCatchPattern":"try { external.buildExternal(config); } catch (IllegalArgumentException e) { throw new ConfigException(\"Change stream config incomplete: \" + e.getMessage(), e); }","preventionTips":["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."],"tags":["java","apache-beam","google-cloud-spanner","change-streams","validation"],"backgroundTag":"empty-required-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}