{"record":{"id":"7b48ac582138ecfb","repo":"apache/iceberg","slug":"s-does-not-have-a-metadata-file-location","errorCode":null,"errorMessage":"%s does not have a metadata file location","messagePattern":"(.+?) does not have a metadata file location","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/TableUtil.java","lineNumber":58,"sourceCode":"      throw new IllegalArgumentException(\n          String.format(\"%s does not have a format version\", table.getClass().getSimpleName()));\n    }\n  }\n\n  /** Returns the metadata file location of the given table */\n  public static String metadataFileLocation(Table table) {\n    Preconditions.checkArgument(null != table, \"Invalid table: null\");\n\n    if (table instanceof SerializableTable) {\n      SerializableTable serializableTable = (SerializableTable) table;\n      return serializableTable.metadataFileLocation();\n    } else if (table instanceof HasTableOperations) {\n      HasTableOperations ops = (HasTableOperations) table;\n      return ops.operations().current().metadataFileLocation();\n    } else if (table instanceof BaseMetadataTable) {\n      return ((BaseMetadataTable) table).table().operations().current().metadataFileLocation();\n    } else {\n      throw new IllegalArgumentException(\n          String.format(\n              \"%s does not have a metadata file location\", table.getClass().getSimpleName()));\n    }\n  }\n\n  public static boolean supportsRowLineage(Table table) {\n    Preconditions.checkArgument(null != table, \"Invalid table: null\");\n    if (table instanceof BaseMetadataTable) {\n      return false;\n    }\n\n    return formatVersion(table) >= TableMetadata.MIN_FORMAT_VERSION_ROW_LINEAGE;\n  }\n}\n","sourceCodeStart":40,"sourceCodeEnd":73,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/TableUtil.java#L40-L73","documentation":"TableUtil.metadataFileLocation(Table) returns the location of the current metadata JSON file, but only when the table's operations are accessible (HasTableOperations or BaseMetadataTable). For other Table implementations there is no metadata file to report, so IllegalArgumentException is thrown with the table class's simple name.","triggerScenarios":"TableUtil.metadataFileLocation(table) on a Table that is neither HasTableOperations nor BaseMetadataTable — e.g. StaticTableOperations-backed StaticTable (whose metadata location isn't surfaced this way), custom decorators, or mocks.","commonSituations":"Tooling that prints/exports the current metadata file path applied to static or wrapped tables; audit/debug utilities assuming all Table handles expose operations; engine adapters passing wrapper objects.","solutions":["Load the table through a catalog so it is a BaseTable with HasTableOperations","For static tables, use the metadata location string you created the table with instead","Unwrap BaseMetadataTable instances before querying the location","Implement HasTableOperations in custom Table wrappers that must report a metadata location"],"exampleFix":"// before\nString loc = TableUtil.metadataFileLocation(customWrapper); // throws\n// after\nString loc = TableUtil.metadataFileLocation(catalog.loadTable(id));","handlingStrategy":"type-guard","validationCode":"boolean hasMetadataLocation(Table t) {\n  return t instanceof BaseMetadataTable || t.operations() instanceof HasTableOperations;\n}","typeGuard":"String safeMetadataFileLocation(Table t) {\n  if (t instanceof BaseMetadataTable) {\n    return ((BaseMetadataTable) t).table().operations().current().metadataFileLocation();\n  }\n  return (t.operations() instanceof HasTableOperations)\n      ? ((HasTableOperations) t).operations().current().metadataFileLocation()\n      : null;\n}","tryCatchPattern":"try { loc = TableUtil.metadataFileLocation(table); }\ncatch (IllegalArgumentException e) { loc = null; /* table impl has no metadata file */ }","preventionTips":["Load tables via Catalog so they expose operations","For StaticTable, keep the original metadata location string and use it directly","Feature-detect with instanceof HasTableOperations before calling TableUtil","Unwrap metadata tables before reading locations"],"tags":["metadata-location","table-util","argument-validation","iceberg"],"backgroundTag":"incompatible-source-type","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"}