{"record":{"id":"d8e7030a3b285eb1","repo":"apache/beam","slug":"to-read-from-pubsub-a-subscription-name-or-a-topic-name-must-d8e703","errorCode":null,"errorMessage":"To read from Pubsub, a subscription name or a topic name must be provided. Not both.","messagePattern":"To read from Pubsub, a subscription name or a topic name must be provided\\. Not both\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/pubsub/PubsubReadSchemaTransformProvider.java","lineNumber":84,"sourceCode":"  public static final TupleTag<Row> OUTPUT_TAG = new TupleTag<Row>() {};\n  public static final TupleTag<Row> ERROR_TAG = new TupleTag<Row>() {};\n  public static final Schema ERROR_SCHEMA =\n      Schema.builder().addStringField(\"error\").addNullableByteArrayField(\"row\").build();\n\n  @Override\n  public Class<PubsubReadSchemaTransformConfiguration> configurationClass() {\n    return PubsubReadSchemaTransformConfiguration.class;\n  }\n\n  @Override\n  public SchemaTransform from(PubsubReadSchemaTransformConfiguration configuration) {\n    if (configuration.getSubscription() == null && configuration.getTopic() == null) {\n      throw new IllegalArgumentException(\n          \"To read from Pubsub, a subscription name or a topic name must be provided\");\n    }\n\n    if (configuration.getSubscription() != null && configuration.getTopic() != null) {\n      throw new IllegalArgumentException(\n          \"To read from Pubsub, a subscription name or a topic name must be provided. Not both.\");\n    }\n\n    if (!\"RAW\".equals(configuration.getFormat())) {\n      if ((Strings.isNullOrEmpty(configuration.getSchema())\n              && !Strings.isNullOrEmpty(configuration.getFormat()))\n          || (!Strings.isNullOrEmpty(configuration.getSchema())\n              && Strings.isNullOrEmpty(configuration.getFormat()))) {\n        throw new IllegalArgumentException(\n            \"A schema was provided without a data format (or viceversa). Please provide \"\n                + \"both of these parameters to read from Pubsub, or if you would like to use the Pubsub schema service,\"\n                + \" please leave both of these blank.\");\n      }\n    }\n\n    Schema payloadSchema;\n    SerializableFunction<byte[], Row> payloadMapper;\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/pubsub/PubsubReadSchemaTransformProvider.java#L66-L102","documentation":"PubsubReadSchemaTransformProvider.from() requires the read configuration to specify exactly one of a Pubsub subscription name or a topic name. It throws when both are set, because reading via both a subscription and a topic is ambiguous — a topic read creates its own subscription semantics, which conflicts with an explicit subscription.","triggerScenarios":"Calling PubsubReadSchemaTransformProvider.from(configurationRow) where the configuration Row has BOTH the 'subscription' and 'topic' fields populated with non-null values.","commonSituations":"Config files or pipeline templates that merge defaults (topic from one place, subscription from another); users who think they must supply both; programmatic config building that copies both fields from a template.","solutions":["Remove one of the two values from the configuration Row — set exactly one of 'subscription' or 'topic'.","If consuming an existing subscription, clear 'topic' and keep 'subscription'.","If reading from a topic without an existing subscription, clear 'subscription' and keep 'topic'.","Validate the merged config before building the transform to ensure the two fields are not both set."],"exampleFix":"// before\nconfig = Config.builder().setTopic(\"projects/p/topics/t\").setSubscription(\"projects/p/subs/s\").build();\n// after\nconfig = Config.builder().setSubscription(\"projects/p/subs/s\").build(); // or setTopic only","handlingStrategy":"validation","validationCode":"if ((cfg.getSubscription() != null) == (cfg.getTopic() != null)) { throw new IllegalArgumentException(\"Provide exactly one of subscription or topic\"); }","typeGuard":null,"tryCatchPattern":"try { return provider.from(cfg); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Not both\")) { /* fix config: clear one field */ } throw e; }","preventionTips":["Decide up front whether you consume a subscription or a topic and keep only that field in config templates.","Add a pre-flight assertion in config-loading code that subscription XOR topic is set."],"tags":["java","apache-beam","pubsub","configuration"],"backgroundTag":"mutually-exclusive-options","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"}