prestodb/presto · error · PrestoException

INVALID_TABLE_PROPERTY

INVALID_TABLE_PROPERTY

Error message

%s must be positive, got %d

What it means

IcebergMaterializedViewProperties validates MV table properties. The max_snapshots_per_refresh property is parsed as an int and must be strictly positive; a value of zero or negative throws PrestoException INVALID_TABLE_PROPERTY with '%s must be positive, got %d'.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergMaterializedViewProperties.java:135

                            null,
                            false),
                    PRESTO_MATERIALIZED_VIEW_USE_TIMESTAMP_BASED_STALENESS),
            updatable(
                    new PropertyMetadata<>(
                            MAX_SNAPSHOTS_PER_REFRESH,
                            "Maximum number of snapshots consumed per base table per refresh. " +
                                    "Unset falls back to the session default.",
                            INTEGER,
                            Integer.class,
                            null,
                            false,
                            value -> {
                                if (value == null) {
                                    return null;
                                }
                                int parsed = ((Number) value).intValue();
                                if (parsed <= 0) {
                                    throw new PrestoException(INVALID_TABLE_PROPERTY,
                                            format("%s must be positive, got %d", MAX_SNAPSHOTS_PER_REFRESH, parsed));
                                }
                                return parsed;
                            },
                            object -> object),
                    PRESTO_MATERIALIZED_VIEW_MAX_SNAPSHOTS_PER_REFRESH,
                    value -> Integer.toString((Integer) value)));

    private static final Map<String, MaterializedViewProperty> MV_ONLY_PROPERTIES_BY_NAME =
            Maps.uniqueIndex(MV_ONLY_PROPERTIES, property -> property.metadata().getName());

    private final List<PropertyMetadata<?>> materializedViewProperties;

    @Inject
    public IcebergMaterializedViewProperties(IcebergTableProperties tableProperties)
    {
        requireNonNull(tableProperties, "tableProperties is null");

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Set the property to a positive integer (e.g. 10) instead of 0 or a negative value
  2. Remove the property entirely to use the default behavior instead of 0
  3. Validate any templated/config-driven value before applying it (coerce and check > 0)
  4. Consult the property definition in IcebergMaterializedViewProperties for the accepted range

Example fix

// before
ALTER MATERIALIZED VIEW sales.daily_mv SET PROPERTIES max_snapshots_per_refresh = 0;
// after
ALTER MATERIALIZED VIEW sales.daily_mv SET PROPERTIES max_snapshots_per_refresh = 10;
Defensive patterns

Strategy: validation

Validate before calling

-- Validate before applying:
-- ensure the value is an integer > 0
SELECT IF(CAST(${max_snapshots_per_refresh} AS BIGINT) > 0, 'ok', 'invalid') AS check;
-- or simply: ALTER ... SET PROPERTIES max_snapshots_per_refresh = 10;

Type guard

// application-side guard
boolean isValidMaxSnapshots(Number v) {
    return v != null && v.intValue() > 0;
}

Try / catch

try {
    stmt.execute("ALTER MATERIALIZED VIEW sales.daily_mv SET PROPERTIES max_snapshots_per_refresh = " + value);
} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().contains("must be positive")) {
        // clamp to a positive default or remove the property, then retry
    } else { throw e; }
}

Prevention

When it happens

Trigger: ALTER MATERIALIZED VIEW ... SET PROPERTIES max_snapshots_per_refresh = 0 (or negative), or a CREATE MATERIALIZED VIEW ... WITH (max_snapshots_per_refresh = <=0) statement.

Common situations: Copy-pasting a config where the value is meant to be 'unlimited' (using 0); arithmetic/templating bugs producing 0 or negative values; misunderstanding that 0 means 'no limit'.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/6ae2b573d80a2592. Report an issue: GitHub.