{"record":{"id":"179236792761b25c","repo":"apache/beam","slug":"metadata-database-can-not-be-null","errorCode":null,"errorMessage":"Metadata database can not be null","messagePattern":"Metadata database can not be null","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/changestreams/dao/DaoFactory.java","lineNumber":86,"sourceCode":"   * @param rpcPriority the priority of the requests made by the DAO queries\n   * @param jobName the name of the running job\n   */\n  public DaoFactory(\n      SpannerConfig changeStreamSpannerConfig,\n      String changeStreamName,\n      List<String> tvfNameList,\n      SpannerConfig metadataSpannerConfig,\n      PartitionMetadataTableNames partitionMetadataTableNames,\n      RpcPriority rpcPriority,\n      String jobName,\n      Dialect spannerChangeStreamDatabaseDialect,\n      Dialect metadataDatabaseDialect,\n      boolean isMutableChangeStream) {\n    if (metadataSpannerConfig.getInstanceId() == null) {\n      throw new IllegalArgumentException(\"Metadata instance can not be null\");\n    }\n    if (metadataSpannerConfig.getDatabaseId() == null) {\n      throw new IllegalArgumentException(\"Metadata database can not be null\");\n    }\n    this.changeStreamSpannerConfig = changeStreamSpannerConfig;\n    this.changeStreamName = changeStreamName;\n    this.tvfNameList =\n        tvfNameList == null ? ChangeStreamsConstants.DEFAULT_TVF_NAME_LIST : tvfNameList;\n    this.metadataSpannerConfig = metadataSpannerConfig;\n    this.partitionMetadataTableNames = partitionMetadataTableNames;\n    this.rpcPriority = rpcPriority;\n    this.jobName = jobName;\n    this.spannerChangeStreamDatabaseDialect = spannerChangeStreamDatabaseDialect;\n    this.metadataDatabaseDialect = metadataDatabaseDialect;\n    this.isMutableChangeStream = isMutableChangeStream;\n  }\n\n  /** Returns the tvf name list. */\n  public List<String> getTvfNameList() {\n    return this.tvfNameList;\n  }","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/changestreams/dao/DaoFactory.java#L68-L104","documentation":"DaoFactory's constructor also requires metadataSpannerConfig.getDatabaseId() to be non-null. The metadata database (which stores change stream partitions and watermarks) must be specified; otherwise IllegalArgumentException is thrown right after the instance check.","triggerScenarios":"Building DaoFactory with a metadata SpannerConfig that has an instanceId but no databaseId — the metadata database option was omitted in the transform configuration.","commonSituations":"Configuration where withMetadataInstance was called but withMetadataDatabase was forgotten; environment-driven config assembly where the metadata database id variable is empty or unset.","solutions":["Set the metadata database on the configuration, e.g. withMetadataDatabase(\"change-stream-metadata\").","If metadata should live in the same database as the change stream source, explicitly set that database id in the metadata config.","Validate the assembled SpannerConfig (instanceId and databaseId non-null) before constructing DaoFactory."],"exampleFix":"// before\n.withMetadataInstance(\"my-instance\")\n// after\n.withMetadataInstance(\"my-instance\")\n.withMetadataDatabase(\"my-metadata-db\")","handlingStrategy":"validation","validationCode":"if (metadataSpannerConfig.getDatabaseId() == null) {\n  throw new IllegalArgumentException(\"Set withMetadataDatabase() before expansion\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair every withMetadataInstance call with a withMetadataDatabase call.","Verify env-driven config values are non-empty before building SpannerConfig.","Run a dry-run/local validation of the configuration before launching the Dataflow job."],"tags":["spanner","config-validation","null","java"],"backgroundTag":"missing-required-config-field","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}