prestodb/presto · error · PrestoException
INVALID_PROCEDURE_ARGUMENT
INVALID_PROCEDURE_ARGUMENT
Error message
Table is not partitioned:
What it means
INVALID_PROCEDURE_ARGUMENT from the system.sync_partition_metadata procedure when invoked on a table that has no partition columns. The procedure synchronizes partition metadata with files on HDFS, which is only meaningful for partitioned tables.
Source
Thrown at presto-hive/src/main/java/com/facebook/presto/hive/SyncPartitionMetadataProcedure.java:136
SyncMode syncMode = toSyncMode(mode);
SemiTransactionalHiveMetastore metastore = hiveMetadataFactory.get().getMetastore();
SchemaTableName schemaTableName = new SchemaTableName(schemaName, tableName);
MetastoreContext metastoreContext = new MetastoreContext(
session.getIdentity(),
session.getQueryId(),
session.getClientInfo(),
session.getClientTags(),
session.getSource(),
getMetastoreHeaders(session),
isUserDefinedTypeEncodingEnabled(session),
metastore.getColumnConverterProvider(),
session.getWarningCollector(),
session.getRuntimeStats());
Table table = metastore.getTable(metastoreContext, schemaName, tableName)
.orElseThrow(() -> new TableNotFoundException(schemaTableName));
if (table.getPartitionColumns().isEmpty()) {
throw new PrestoException(INVALID_PROCEDURE_ARGUMENT, "Table is not partitioned: " + schemaTableName);
}
Path tableLocation = new Path(table.getStorage().getLocation());
HdfsContext context = new HdfsContext(session, schemaName, tableName, table.getStorage().getLocation(), false);
Set<String> partitionsToAdd;
Set<String> partitionsToDrop;
try {
FileSystem fileSystem = hdfsEnvironment.getFileSystem(context, tableLocation);
List<PartitionNameWithVersion> partitionNamesInMetastore = metastore.getPartitionNames(metastoreContext, schemaName, tableName)
.orElseThrow(() -> new TableNotFoundException(schemaTableName));
ImmutableList.Builder<String> partitionsInMetastore = new ImmutableList.Builder<>();
for (List<PartitionNameWithVersion> batchPartitionNames : partition(partitionNamesInMetastore, GET_PARTITION_BY_NAMES_BATCH_SIZE)) {
Map<String, Optional<Partition>> partitionsOptionalMap = metastore.getPartitionsByNames(metastoreContext, schemaName, tableName, batchPartitionNames);
for (Map.Entry<String, Optional<Partition>> entry : partitionsOptionalMap.entrySet()) {
if (entry.getValue().isPresent()) {
partitionsInMetastore.add(tableLocation.toUri().relativize(new Path(entry.getValue().get().getStorage().getLocation()).toUri()).getPath());
}View on GitHub (pinned to 55bb57d202)
Solutions
- Confirm the table is partitioned: SHOW CREATE TABLE and check PARTITIONED BY; only run the procedure on partitioned tables
- Correct the schema/table name arguments if you meant a different table
- For unpartitioned tables there is nothing to sync; skip the call or drop/re-register the table if metadata is stale
Example fix
// before
CALL system.sync_partition_metadata('default', 'events_flat', 'FULL');
// after: verify first, then target a partitioned table
SHOW CREATE TABLE default.events_flat; -- confirm PARTITIONED BY
CALL system.sync_partition_metadata('default', 'events_partitioned', 'FULL'); Defensive patterns
Strategy: validation
Validate before calling
-- before calling the procedure
SHOW CREATE TABLE schema.table; -- must show PARTITIONED BY
-- or programmatic:
Table t = metastore.getTable(metastoreContext, schema, tableName)
.orElseThrow(() -> new IllegalArgumentException("table missing"));
if (t.getPartitionColumns().isEmpty()) {
throw new IllegalArgumentException("Not partitioned, skip sync: " + schema + "." + tableName);
} Type guard
static boolean isPartitioned(Table table) {
return table != null && !table.getPartitionColumns().isEmpty();
} Try / catch
try {
session.execute("CALL system.sync_partition_metadata('schema','table','FULL')");
} catch (PrestoException e) {
if (StandardErrorCode.INVALID_PROCEDURE_ARGUMENT.toErrorCode().equals(e.getErrorCode())
&& e.getMessage().startsWith("Table is not partitioned:")) {
// skip or correct the table name
} else throw e;
} Prevention
- Check SHOW CREATE TABLE for PARTITIONED BY before running sync_partition_metadata
- Validate schema/table arguments in maintenance scripts
- Filter candidate tables to partitioned ones (e.g. via SHOW PARTITIONS probing)
- Skip non-partitioned tables explicitly in scheduled sync jobs
When it happens
Trigger: CALL system.sync_partition_metadata('schema','table','ADD'|'DROP'|'FULL') on a non-partitioned table: metastore.getTable succeeds but table.getPartitionColumns().isEmpty() is true in doSyncPartitionMetadata.
Common situations: Running the procedure against an unpartitioned table by mistake; passing wrong table name that resolves to a plain table; assuming all tables in a schema are partitioned in scripted maintenance jobs.
Related errors
- HIVE_INVALID_METADATA
- HIVE_INVALID_PARTITION_VALUE
- INVALID_ANALYZE_PROPERTY
- HIVE_COLUMN_ORDER_MISMATCH
- HIVE_INVALID_PARTITION_VALUE
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1e1c54aac7e9d371.
Report an issue: GitHub.