{"record":{"id":"a1d38fefd6bd52a8","repo":"apache/iceberg","slug":"msg","errorCode":null,"errorMessage":"${msg}","messagePattern":"\\$\\{msg\\}","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/IcebergSinkConfig.java","lineNumber":300,"sourceCode":"\n    validate();\n  }\n\n  private void validate() {\n    checkState(!catalogProps().isEmpty(), \"Must specify Iceberg catalog properties\");\n    if (tables() != null) {\n      checkState(!dynamicTablesEnabled(), \"Cannot specify both static and dynamic table names\");\n    } else if (dynamicTablesEnabled()) {\n      checkState(\n          tablesRouteField() != null, \"Must specify a route field if using dynamic table names\");\n    } else {\n      throw new ConfigException(\"Must specify table name(s)\");\n    }\n  }\n\n  private void checkState(boolean condition, String msg) {\n    if (!condition) {\n      throw new ConfigException(msg);\n    }\n  }\n\n  public String connectorName() {\n    return originalProps.get(NAME_PROP);\n  }\n\n  public String taskId() {\n    return originalProps.get(TASK_ID);\n  }\n\n  public String transactionalSuffix() {\n    // this is for internal use and is not part of the config definition...\n    return originalProps.get(INTERNAL_TRANSACTIONAL_SUFFIX_PROP);\n  }\n\n  public Map<String, String> catalogProps() {\n    return catalogProps;","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/IcebergSinkConfig.java#L282-L318","documentation":"IcebergSinkConfig.checkState is a helper that converts a failed boolean condition during configuration validation into a ConfigException with the given message. The thrown message '${msg}' is whatever validation text was passed in — e.g. 'Cannot specify both static and dynamic table names' or 'Must specify a route field if using dynamic table names'.","triggerScenarios":"Called from validate() when: both iceberg.tables and iceberg.tables.dynamic-enabled=true are set, or dynamic tables are enabled without iceberg.tables.route-field.","commonSituations":"Developers partially migrating between static and dynamic table routing — enabling dynamic mode while leaving static tables configured, or enabling dynamic mode without specifying the record field used for routing.","solutions":["If the message says both were specified, remove 'iceberg.tables' or set 'iceberg.tables.dynamic-enabled=false'.","If the message mentions a route field, set 'iceberg.tables.route-field' to the record field that determines the target table.","Read the ConfigException message itself — it names the exact violated rule."],"exampleFix":"// before\n\"iceberg.tables\": \"db.t1\",\n\"iceberg.tables.dynamic-enabled\": \"true\"\n// after\n\"iceberg.tables.dynamic-enabled\": \"true\",\n\"iceberg.tables.route-field\": \"targetTable\"","handlingStrategy":"validation","validationCode":"// Reject mutually exclusive / incomplete dynamic routing config up front\nboolean dyn = Boolean.parseBoolean(config.getOrDefault(\"iceberg.tables.dynamic-enabled\", \"false\"));\nif (dyn && config.get(\"iceberg.tables\") != null) throw new IllegalArgumentException(\"remove iceberg.tables when dynamic routing is enabled\");\nif (dyn && config.get(\"iceberg.tables.route-field\") == null) throw new IllegalArgumentException(\"iceberg.tables.route-field is required for dynamic routing\");","typeGuard":null,"tryCatchPattern":"try { new IcebergSinkConfig(props); } catch (org.apache.kafka.common.config.ConfigException e) { log.error(\"Config rule violated: {}\", e.getMessage()); }","preventionTips":["Don't mix static 'iceberg.tables' with dynamic routing","Always pair dynamic-enabled=true with tables.route-field","Test config changes in staging before production connectors"],"tags":["kafka-connect","iceberg","config"],"backgroundTag":"conflicting-config-options","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}