{"record":{"id":"9189435174010b06","repo":"apache/iceberg","slug":"does-not-support-time-travel","errorCode":null,"errorMessage":" does not support time travel","messagePattern":" does not support time travel","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java","lineNumber":66,"sourceCode":"\n    String groupId = ident.name();\n    Table table = TABLE_CACHE.get(groupId);\n\n    if (table == null) {\n      throw new NoSuchTableException(ident);\n    }\n\n    return new SparkRewriteTable(table, groupId);\n  }\n\n  @Override\n  public SparkTable loadTable(Identifier ident, String version) throws NoSuchTableException {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support time travel\");\n  }\n\n  @Override\n  public SparkTable loadTable(Identifier ident, long timestampMicros) throws NoSuchTableException {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support time travel\");\n  }\n\n  @Override\n  public void invalidateTable(Identifier ident) {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support table invalidation\");\n  }\n\n  @Override\n  public SparkTable createTable(Identifier ident, TableInfo tableInfo)\n      throws TableAlreadyExistsException {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support creating tables\");\n  }\n\n  @Override\n  public SparkTable alterTable(Identifier ident, TableChange... changes) {\n    throw new UnsupportedOperationException(CLASS_NAME + \" does not support altering tables\");\n  }\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/SparkRewriteTableCatalog.java#L48-L84","documentation":"The timestamp-based loadTable(ident, timestampMicros) overload on SparkRewriteTableCatalog always throws UnsupportedOperationException ('<class> does not support time travel') because rewriting operates on the current table snapshot only.","triggerScenarios":"Calling loadTable(ident, timestampMicros) on SparkRewriteTableCatalog, or Spark resolving a timestampAsOf/AS OF query against the rewrite catalog.","commonSituations":"Rewrite procedures with time-travel options; querying historical snapshots through a catalog configured as the rewrite catalog; generic catalog clients using the timestamped overload.","solutions":["Drop timestampAsOf/AS OF clauses when using the rewrite catalog.","Use SparkCatalog for time-travel reads: SELECT ... TIMESTAMP AS OF <ts>.","Keep rewrite operations pointed at the current snapshot only."],"exampleFix":"// before\nTable t = rewriteCatalog.loadTable(ident, tsMicros);\n// after\nTable t = sparkCatalog.loadTable(ident, tsMicros); // timestamp travel via the real catalog","handlingStrategy":"validation","validationCode":"if (catalog instanceof SparkRewriteTableCatalog && timestampMicros > 0) {\n  throw new IllegalArgumentException(\"timestampAsOf is not supported by SparkRewriteTableCatalog\");\n}","typeGuard":"boolean supportsTimestampTravel(CatalogPlugin c) {\n  return !(c instanceof SparkRewriteTableCatalog);\n}","tryCatchPattern":"try {\n  Table t = catalog.loadTable(ident, tsMicros);\n} catch (UnsupportedOperationException e) {\n  Table t = sparkCatalog.loadTable(ident, tsMicros);\n}","preventionTips":["Strip AS OF / timestampAsOf clauses when targeting the rewrite catalog.","Use SparkCatalog for historical reads.","Do not configure the rewrite catalog as a session default.","Remember rewrite operates on current state only."],"tags":["spark","rewrite","time-travel","unsupported-operation"],"backgroundTag":"operation-not-supported","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"}