{"record":{"id":"c6cda75ab3e72021","repo":"apache/beam","slug":"table-and-query-are-mutually-exclusive","errorCode":null,"errorMessage":"table and query are mutually exclusive.","messagePattern":"table and query are mutually exclusive\\.","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/SnowflakeReadSchemaTransformProvider.java","lineNumber":234,"sourceCode":"\n      SnowflakeSchemaTransformUtils.validateAuthentication(\n          getUsername(),\n          getPassword(),\n          getOauthToken(),\n          getPrivateKey(),\n          getPrivateKeyPassphrase());\n\n      String table = getTable();\n      boolean tablePresent = table != null && !table.isEmpty();\n      String query = getQuery();\n      boolean queryPresent = query != null && !query.isEmpty();\n\n      if (!tablePresent && !queryPresent) {\n        throw new IllegalArgumentException(\"Either table or query must be specified.\");\n      }\n\n      if (tablePresent && queryPresent) {\n        throw new IllegalArgumentException(\"table and query are mutually exclusive.\");\n      }\n\n      if (!getStagingBucketName().endsWith(\"/\")) {\n        throw new IllegalArgumentException(\"stagingBucketName must end with '/'\");\n      }\n\n      // Validate JSON schema early.\n      JsonUtils.beamSchemaFromJsonSchema(getSchema());\n    }\n\n    private static void requireNonEmpty(String value, String name) {\n      if (value == null || value.isEmpty()) {\n        throw new IllegalArgumentException(name + \" cannot be empty\");\n      }\n    }\n\n    @AutoValue.Builder\n    public abstract static class Builder {","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/SnowflakeReadSchemaTransformProvider.java#L216-L252","documentation":"SnowflakeReadSchemaTransformProvider.validate enforces that a read source is specified exactly one way: table and query are mutually exclusive, and both being present makes the source ambiguous, so this IllegalArgumentException fires. (A sibling check rejects neither being present.)","triggerScenarios":"Setting both setTable(\"t\") and setQuery(\"SELECT ...\") on SnowflakeReadSchemaTransformConfiguration, or a YAML config that includes both keys.","commonSituations":"Template config with table filled in plus a pasted query; merging default config with user overrides where both survive; script-generated configs concatenating options.","solutions":["Remove the table entry and keep the query, or vice versa.","If a query is needed for filtering, drop the table and write SELECT ... FROM <table> in the query.","In YAML, delete the unused key rather than leaving it empty-but-present logic aside (both non-empty triggers this).","Centralize read-source configuration so table/query can't both be set programmatically."],"exampleFix":"// before\nconfiguration.setTable(\"events\").setQuery(\"SELECT * FROM events LIMIT 10\");\n// after\nconfiguration.setQuery(\"SELECT * FROM events LIMIT 10\");","handlingStrategy":"validation","validationCode":"if (table != null && !table.isEmpty() && query != null && !query.isEmpty()) {\n  throw new IllegalArgumentException(\"Provide only one of table or query\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remove (not empty) the unused key in configs.","Keep a single source-of-truth for the read source.","Code-review template merges for duplicated options."],"tags":["java","snowflake","validation","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-20T03:17:13.778Z"}