{"record":{"id":"cba800c3010f625c","repo":"apache/beam","slug":"provider-is-already-registered-for-table-type-type","errorCode":null,"errorMessage":"Provider is already registered for table type: ${type}","messagePattern":"Provider is already registered for table type: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/store/InMemoryMetaStore.java","lineNumber":105,"sourceCode":"  protected void validateTableType(Table table) {\n    if (providers.containsKey(table.getType().toLowerCase())) {\n      return;\n    }\n    // check if there is a nested metastore that supports this table\n    @Nullable InMemoryMetaStore nestedMemoryMetastore =\n        (InMemoryMetaStore) providers.get(getTableType());\n    if (nestedMemoryMetastore != null) {\n      nestedMemoryMetastore.validateTableType(table);\n    } else {\n      throw new IllegalArgumentException(\"Table type: \" + table.getType() + \" not supported!\");\n    }\n  }\n\n  @Override\n  public void registerProvider(TableProvider provider) {\n    String type = provider.getTableType().toLowerCase();\n    if (providers.containsKey(type)) {\n      throw new IllegalArgumentException(\"Provider is already registered for table type: \" + type);\n    }\n\n    initTablesFromProvider(provider);\n    this.providers.put(type, provider);\n  }\n\n  private void initTablesFromProvider(TableProvider provider) {\n    Map<String, Table> tables = provider.getTables();\n    for (String tableName : tables.keySet()) {\n      if (this.tables.containsKey(tableName)) {\n        throw new IllegalStateException(\n            \"Duplicate table: \" + tableName + \" from provider: \" + provider);\n      }\n    }\n    this.tables.putAll(tables);\n  }\n\n  @Override","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/store/InMemoryMetaStore.java#L87-L123","documentation":"InMemoryMetaStore.registerProvider rejects registering two providers for the same (lowercased) table type string with IllegalArgumentException. The type string is the map key, so duplicates would silently overwrite an existing provider.","triggerScenarios":"Calling registerProvider twice with providers whose getTableType() normalize to the same string, e.g. two TextTableProvider instances or a custom provider declaring type 'text'.","commonSituations":"Test suites registering providers in both @BeforeEach and constructor; app initialization paths that may run more than once; two custom providers accidentally using the same type name.","solutions":["Guard registration: only register when the type is not yet present.","Register providers once during single-time initialization (e.g. static/singleton setup).","Give the second provider a distinct getTableType() value."],"exampleFix":"// before\nmetaStore.registerProvider(new TextTableProvider());\nmetaStore.registerProvider(new TextTableProvider()); // throws\n// after\nif (metaStore.getTables() != null && !metaStoreProvidersContains(metaStore, \"text\")) {\n  metaStore.registerProvider(new TextTableProvider());\n} // or simply register once in setup","handlingStrategy":"validation","validationCode":"if (!registeredTypes.add(provider.getTableType().toLowerCase())) {\n  return; // already registered\n}\nmetaStore.registerProvider(provider);","typeGuard":null,"tryCatchPattern":"try {\n  metaStore.registerProvider(provider);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Provider is already registered\")) { /* benign re-init */ }\n}","preventionTips":["Register providers exactly once (static init or singleton).","Track registered types in your own set for idempotency.","Use unique getTableType() names for custom providers."],"tags":["beam-sql","metastore","duplicate-registration"],"backgroundTag":"conflicting-config-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"}