{"record":{"id":"f007a024feb9c104","repo":"apache/iceberg","slug":"this-getclass-getname-does-not-support-oper","errorCode":null,"errorMessage":"${this.getClass().getName()} does not support operations()","messagePattern":"(.+?) does not support operations\\(\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SerializableTable.java","lineNumber":461,"sourceCode":"\n  public static class SerializableMetadataTable extends SerializableTable {\n    private final MetadataTableType type;\n    private final String baseTableName;\n\n    protected SerializableMetadataTable(BaseMetadataTable metadataTable) {\n      super(metadataTable);\n      this.type = metadataTable.metadataTableType();\n      this.baseTableName = metadataTable.table().name();\n    }\n\n    @Override\n    protected Table newTable(TableOperations ops, String tableName) {\n      return MetadataTableUtils.createMetadataTableInstance(ops, baseTableName, tableName, type);\n    }\n\n    @Override\n    public StaticTableOperations operations() {\n      throw new UnsupportedOperationException(\n          this.getClass().getName() + \" does not support operations()\");\n    }\n\n    public MetadataTableType type() {\n      return type;\n    }\n  }\n}\n","sourceCodeStart":443,"sourceCodeEnd":470,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SerializableTable.java#L443-L470","documentation":"SerializableMetadataTable is the serializable wrapper for Iceberg metadata tables (e.g. table.files, table.history, table.refs). Unlike the plain SerializableTable, whose operations() lazily wraps a StaticTableOperations, metadata tables are instantiated through MetadataTableUtils and expose no StaticTableOperations, so operations() is intentionally unimplemented and always throws UnsupportedOperationException.","triggerScenarios":"Calling operations() on a serialized metadata table (SerializableMetadataTable), typically obtained when a metadata table instance was passed through serialization (broadcast/closure) or cast to a type exposing operations(); code paths that require HasTableOperations on metadata tables also hit this.","commonSituations":"Engine integration or utility code that inspects TableOperations of a metadata table after distribution; Kryo/Java deserialization of metadata tables (e.g. files/meta tables) in Spark executors followed by API calls needing operations().","solutions":["Do not call operations() on metadata tables; instead use the metadata-table-specific APIs (e.g. scan via newScan(), MetadataTableType via type()).","If the underlying base table's operations are needed, keep a reference to the original BaseMetadataTable (or reload it from the catalog) and call operations() on the base table, not the serialized wrapper.","Recreate the metadata table on demand with MetadataTableUtils.createMetadataTableInstance(ops, baseTableName, tableName, type) instead of deserializing it."],"exampleFix":"// before\nTableOperations ops = ((HasTableOperations) serializedMetadataTable).operations(); // throws\n\n// after\nTable base = catalog.loadTable(baseTableLocation);\nMetadataTableUtils.createMetadataTableInstance(base.operations(), baseTableName, name, type);","handlingStrategy":"type-guard","validationCode":"if (table instanceof org.apache.iceberg.SerializableTable.SerializableMetadataTable) {\n  // operations() is unsupported; use newScan()/type() or recreate via MetadataTableUtils\n}","typeGuard":"boolean supportsOperationsAccess(Table t) {\n  return t instanceof org.apache.iceberg.HasTableOperations\n      && !(t instanceof org.apache.iceberg.SerializableTable.SerializableMetadataTable);\n}","tryCatchPattern":"try {\n  TableOperations ops = ((HasTableOperations) table).operations();\n  // ...\n} catch (UnsupportedOperationException e) {\n  // recreate the metadata table from the base table's operations\n  Table base = catalog.loadTable(baseTableLocation);\n  Table meta = MetadataTableUtils.createMetadataTableInstance(\n      ((HasTableOperations) base).operations(), baseTableName, tableName, type);\n}","preventionTips":["Access metadata tables through scan APIs (newScan) rather than TableOperations.","Keep metadata-table wrappers from crossing serialization boundaries; recreate them from the base table.","When operations() is genuinely required, hold a reference to the original BaseMetadataTable or reload it from the catalog."],"tags":["java","unsupported-operation","metadata-table","serialization"],"backgroundTag":"unsupported-operation","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"}