{"record":{"id":"15c5e30550f25353","repo":"apache/iceberg","slug":"cannot-rename-table-s-to-s-s-does-not-exist","errorCode":null,"errorMessage":"Cannot rename table %s to %s: %s does not exist","messagePattern":"Cannot rename table (.+?) to (.+?): (.+?) does not exist","errorType":"exception","errorClass":"NoSuchTableException","httpStatus":404,"severity":"error","filePath":"aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbCatalog.java","lineNumber":441,"sourceCode":"      throw e;\n    }\n  }\n\n  @Override\n  public void renameTable(TableIdentifier from, TableIdentifier to) {\n    Map<String, AttributeValue> fromKey = tablePrimaryKey(from);\n    Map<String, AttributeValue> toKey = tablePrimaryKey(to);\n\n    GetItemResponse fromResponse =\n        dynamo.getItem(\n            GetItemRequest.builder()\n                .tableName(awsProperties.dynamoDbTableName())\n                .consistentRead(true)\n                .key(fromKey)\n                .build());\n\n    if (!fromResponse.hasItem()) {\n      throw new NoSuchTableException(\n          \"Cannot rename table %s to %s: %s does not exist\", from, to, from);\n    }\n\n    GetItemResponse toResponse =\n        dynamo.getItem(\n            GetItemRequest.builder()\n                .tableName(awsProperties.dynamoDbTableName())\n                .consistentRead(true)\n                .key(toKey)\n                .build());\n\n    if (toResponse.hasItem()) {\n      throw new AlreadyExistsException(\n          \"Cannot rename table %s to %s: %s already exists\", from, to, to);\n    }\n\n    fromResponse.item().entrySet().stream()\n        .filter(e -> isProperty(e.getKey()))","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbCatalog.java#L423-L459","documentation":"DynamoDbCatalog.renameTable() validates that the source table exists before performing the rename; if the GetItem for the `from` key returns no item it throws NoSuchTableException with this message. A rename is implemented as read-source + write-new-key + delete-old-key, so the source row is mandatory.","triggerScenarios":"Calling catalog.renameTable(from, to) when the source table's item is absent from the DynamoDB catalog table — the source was already dropped/renamed or `from` never existed.","commonSituations":"Concurrent renames where two jobs both move the same table and the second sees the source gone; renaming after a failed pipeline already dropped the table; wrong environment/identifier in migration scripts.","solutions":["Verify the source table exists with catalog.tableExists(from) before renaming.","If a previous rename attempt may have partially succeeded, check whether the destination table already exists and skip the rename.","Catch org.apache.iceberg.exceptions.NoSuchTableException and reconcile catalog state in retry logic."],"exampleFix":"// before\ncatalog.renameTable(from, to);\n\n// after\nif (catalog.tableExists(from)) {\n  catalog.renameTable(from, to);\n}","handlingStrategy":"validation","validationCode":"if (!catalog.tableExists(from)) {\n  throw new IllegalStateException(\"Source table \" + from + \" does not exist; cannot rename\");\n}\ncatalog.renameTable(from, to);","typeGuard":null,"tryCatchPattern":"try {\n  catalog.renameTable(from, to);\n} catch (NoSuchTableException e) {\n  // check whether a prior rename attempt moved the table already\n  if (!catalog.tableExists(to)) throw e;\n}","preventionTips":["Make rename retries idempotent by checking the destination after a failure","Verify the source exists in the same environment/region as the catalog","Use single-writer jobs for renames to avoid races"],"tags":["aws","dynamodb","catalog","rename","table-not-found"],"backgroundTag":"resource-not-found","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"}