{"record":{"id":"6ce15d49a8c9e9f0","repo":"apache/beam","slug":"failed-to-fetch-partition-mode-for-change-stream-dialect","errorCode":null,"errorMessage":"Failed to fetch partition_mode for change stream '{}', dialect={} - will propagate exception","messagePattern":"Failed to fetch partition_mode for change stream '(.+?)', dialect=(.+?) - will propagate exception","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerIO.java","lineNumber":3135,"sourceCode":"                    \"select option_value\\n\"\n                        + \"from information_schema.change_stream_options\\n\"\n                        + \"where change_stream_name = @changeStreamName and  option_name = 'partition_mode'\")\n                .bind(\"changeStreamName\")\n                .to(changeStreamName)\n                .build();\n      }\n      ResultSet resultSet = tx.executeQuery(statement);\n      while (resultSet.next()) {\n        String value = resultSet.getString(0);\n        if (value != null) {\n          return value;\n        }\n      }\n      return \"\";\n    } catch (RuntimeException e) {\n      // Log the failure (with stack trace) but rethrow so the caller still observes\n      // the error.\n      LOG.warn(\n          \"Failed to fetch partition_mode for change stream '{}', dialect={} - will propagate exception\",\n          changeStreamName,\n          dialect,\n          e);\n      throw e;\n    }\n  }\n}\n","sourceCodeStart":3117,"sourceCodeEnd":3144,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/SpannerIO.java#L3117-L3144","documentation":"SpannerIO failed to fetch the partition_mode configuration for a change stream (checking whether the change stream supports partitioned reads via the given database dialect). The failure is logged with a stack trace and the RuntimeException is rethrown so the caller still sees the error and the read fails rather than silently defaulting.","triggerScenarios":"A RuntimeException is thrown while querying Spanner metadata (e.g., INFORMATION_SCHEMA or change stream options) for the named change stream: change stream does not exist, database unavailable, permission denied, or dialect-specific query not supported (e.g., querying partition_mode on a dialect that lacks it).","commonSituations":"Misspelled change stream name, using PostgreSQL-dialect Spanner databases where partition_mode metadata is unavailable, IAM lacking spanner.database read permissions, transient Spanner unavailability during job setup.","solutions":["Verify the change stream name exists in the database (SELECT * FROM INFORMATION_SCHEMA.CHANGE_STREAMS)","Check the database dialect (GoogleSQL vs PostgreSQL) — partition_mode metadata may not exist for your dialect","Inspect the rethrown exception's cause for the underlying Spanner status and fix permissions/connectivity","Retry if the failure was transient Spanner unavailability"],"exampleFix":"// before\nString changeStreamName = \"myStream\";\n// after\n// confirm existence first:\n// SELECT change_stream_name FROM INFORMATION_SCHEMA.CHANGE_STREAMS WHERE change_stream_name = 'myStream';\nString changeStreamName = \"myStream\"; // must exist for the configured dialect","handlingStrategy":"validation","validationCode":"// before building the SpannerIO read\nboolean exists = querySpanner(\n  \"SELECT change_stream_name FROM INFORMATION_SCHEMA.CHANGE_STREAMS WHERE change_stream_name = ?\",\n  changeStreamName);\nif (!exists) throw new IllegalArgumentException(\"unknown change stream: \" + changeStreamName);","typeGuard":null,"tryCatchPattern":"try {\n  String mode = fetchPartitionMode(changeStreamName, dialect);\n} catch (RuntimeException e) {\n  throw new IllegalStateException(\n    \"Cannot fetch partition_mode for change stream \" + changeStreamName + \" (dialect \" + dialect + \")\", e);\n}","preventionTips":["Verify change stream names against INFORMATION_SCHEMA.CHANGE_STREAMS before configuring the read","Confirm the database dialect and use a SpannerIO version matching it (Postgres-dialect support is newer)","Grant spanner.databaseReader IAM on the database","Add retries for transient Spanner unavailability during pipeline setup"],"tags":["gcp","spanner","change-stream"],"backgroundTag":"resource-not-found","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"}