{"record":{"id":"7abb386cbf2ce61e","repo":"prestodb/presto","slug":"not-supported-7abb38","errorCode":"NOT_SUPPORTED","errorMessage":"Cannot delete from non-managed Hive table","messagePattern":"Cannot delete from non-managed Hive table","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/SemiTransactionalHiveMetastore.java","lineNumber":607,"sourceCode":"                new MetastoreContext(\n                        session.getIdentity(),\n                        session.getQueryId(),\n                        session.getClientInfo(),\n                        session.getClientTags(),\n                        session.getSource(),\n                        getMetastoreHeaders(session),\n                        isUserDefinedTypeEncodingEnabled(session),\n                        columnConverterProvider,\n                        session.getWarningCollector(),\n                        session.getRuntimeStats()),\n                databaseName,\n                tableName);\n        SchemaTableName schemaTableName = new SchemaTableName(databaseName, tableName);\n        if (!table.isPresent()) {\n            throw new TableNotFoundException(schemaTableName);\n        }\n        if (!table.get().getTableType().equals(MANAGED_TABLE) && !table.get().getTableType().equals(MATERIALIZED_VIEW)) {\n            throw new PrestoException(NOT_SUPPORTED, \"Cannot delete from non-managed Hive table\");\n        }\n        if (!table.get().getPartitionColumns().isEmpty()) {\n            throw new IllegalArgumentException(\"Table is partitioned\");\n        }\n\n        Path path = new Path(table.get().getStorage().getLocation());\n        HdfsContext context = new HdfsContext(session, databaseName, tableName, table.get().getStorage().getLocation(), false);\n        setExclusive((delegate, hdfsEnvironment) -> {\n            RecursiveDeleteResult recursiveDeleteResult = recursiveDeleteFiles(hdfsEnvironment, context, path, ImmutableSet.of(\"\"), false);\n            if (!recursiveDeleteResult.getNotDeletedEligibleItems().isEmpty()) {\n                throw new PrestoException(HIVE_FILESYSTEM_ERROR, format(\n                        \"Error deleting from unpartitioned table %s. These items can not be deleted: %s\",\n                        schemaTableName,\n                        recursiveDeleteResult.getNotDeletedEligibleItems()));\n            }\n            return EMPTY_HIVE_COMMIT_HANDLE;\n        });\n    }","sourceCodeStart":589,"sourceCodeEnd":625,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/SemiTransactionalHiveMetastore.java#L589-L625","documentation":"truncateUnpartitionedTable implements DELETE FROM by recursively deleting the table's data files. This is only safe for MANAGED_TABLE (and MATERIALIZED_VIEW) types; for external or other table types Presto refuses with a PrestoException(NOT_SUPPORTED) because deleting files would destroy data it does not own.","triggerScenarios":"Running DELETE FROM <external/non-managed table> (without a WHERE clause that can be handled another way) on a Hive table whose TableType is not MANAGED_TABLE or MATERIALIZED_VIEW.","commonSituations":"Pointing a Hive connector at external tables on S3/HDFS and attempting a full-table DELETE; config mistakes where tables expected to be managed were created as EXTERNAL; deletion jobs that assume managed storage.","solutions":["Recreate the table as a managed table (without EXTERNAL) if deletion of data is intended","Delete rows with a WHERE-based delete or rebuild the table via CTAS filtered to the desired rows","Manually remove/replace the underlying files and refresh, accepting external-table semantics","Use a different connector/storage that supports DELETE on external data"],"exampleFix":"// before\nCREATE EXTERNAL TABLE t (...) LOCATION 's3://bucket/t/';\nDELETE FROM t; -- NOT_SUPPORTED\n// after\nCREATE TABLE t (...) LOCATION 's3://bucket/t/'; -- managed\nDELETE FROM t;","handlingStrategy":"validation","validationCode":"Optional<Table> t = metastore.getTable(metastoreContext, db, tbl);\nif (t.isPresent() && !t.get().getTableType().equals(MANAGED_TABLE)\n        && !t.get().getTableType().equals(MATERIALIZED_VIEW)) {\n    throw new IllegalStateException(\"Refusing DELETE on non-managed table \" + db + \".\" + tbl);\n}","typeGuard":"boolean isDeletable(Table t) {\n    return t.getTableType().equals(MANAGED_TABLE) || t.getTableType().equals(MATERIALIZED_VIEW);\n}","tryCatchPattern":"try {\n    metastore.truncateUnpartitionedTable(session, db, tbl);\n} catch (PrestoException e) {\n    if (e.getErrorCode() == NOT_SUPPORTED.toErrorCode()) {\n        // fall back to CTAS-rebuild or reject the delete request\n    } else throw e;\n}","preventionTips":["Check TableType before DELETE on Hive tables","Avoid full DELETE on EXTERNAL tables","Document that external data must be managed out-of-band"],"tags":["hive","delete","not-supported","external-table"],"backgroundTag":"delete-not-supported","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}