{"record":{"id":"39410bfe068beb6e","repo":"prestodb/presto","slug":"invalid-function-argument-39410b","errorCode":"INVALID_FUNCTION_ARGUMENT","errorMessage":"second argument of max_n/min_n must be positive","messagePattern":"second argument of max_n/min_n must be positive","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/operator/aggregation/AbstractMinMaxNAggregationFunction.java","lineNumber":128,"sourceCode":"\n        Class<? extends Accumulator> accumulatorClass = AccumulatorCompiler.generateAccumulatorClass(\n                Accumulator.class,\n                metadata,\n                classLoader);\n        Class<? extends GroupedAccumulator> groupedAccumulatorClass = AccumulatorCompiler.generateAccumulatorClass(\n                GroupedAccumulator.class,\n                metadata,\n                classLoader);\n        return new BuiltInAggregationFunctionImplementation(getSignature().getNameSuffix(), inputTypes, ImmutableList.of(intermediateType), outputType,\n                true, false, metadata, accumulatorClass, groupedAccumulatorClass);\n    }\n\n    public static void input(BlockComparator comparator, Type type, MinMaxNState state, Block block, long n, int blockIndex)\n    {\n        TypedHeap heap = state.getTypedHeap();\n        if (heap == null) {\n            if (n <= 0) {\n                throw new PrestoException(INVALID_FUNCTION_ARGUMENT, \"second argument of max_n/min_n must be positive\");\n            }\n            checkCondition(n <= MAX_NUMBER_OF_VALUES, INVALID_FUNCTION_ARGUMENT, \"second argument of max_n/min_n must be less than or equal to %s; found %s\", MAX_NUMBER_OF_VALUES, n);\n            heap = new TypedHeap(comparator, type, toIntExact(n));\n            state.setTypedHeap(heap);\n        }\n        else {\n            checkCondition(n == heap.getCapacity(), INVALID_FUNCTION_ARGUMENT, \"Count argument is not constant: found multiple values [%s, %s]\", n, heap.getCapacity());\n        }\n        long startSize = heap.getEstimatedSize();\n        heap.add(block, blockIndex);\n        state.addMemoryUsage(heap.getEstimatedSize() - startSize);\n    }\n\n    public static void combine(MinMaxNState state, MinMaxNState otherState)\n    {\n        TypedHeap otherHeap = otherState.getTypedHeap();\n        if (otherHeap == null) {\n            return;","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/operator/aggregation/AbstractMinMaxNAggregationFunction.java#L110-L146","documentation":"INVALID_FUNCTION_ARGUMENT thrown by the max_n/min_n aggregation's input function when the second argument n is not positive (n <= 0) on the first invocation that allocates the heap. These aggregations keep a TypedHeap of the n largest/smallest values, so n must be >= 1 and <= MAX_NUMBER_OF_VALUES.","triggerScenarios":"Calling max_n(value, n) or min_n(value, n) where n is a constant or column value <= 0, evaluated on the first row processed for a group. Note n is only validated when the heap is not yet allocated, so per-row variable n only errors on the first non-positive value per group.","commonSituations":"Passing a negative or zero constant literal; supplying n from a column with zero/negative values; mathematical expressions that evaluate to 0 or negative for some groups.","solutions":["Ensure the second argument is a positive constant, e.g. max_n(x, 5) instead of max_n(x, 0).","If n comes from a column, filter or coerce: max_n(x, GREATEST(n, 1)) or WHERE n > 0.","Check that any expression computing n cannot evaluate to 0 or negative (integer division truncation, sign errors).","Wrap with TRY() if you want the offending rows to yield NULL instead of failing the query."],"exampleFix":"// before\nSELECT max_n(value, 0) FROM t;\n// after\nSELECT max_n(value, 1) FROM t; -- or a positive n appropriate to the analysis","handlingStrategy":"validation","validationCode":"-- ensure n is a positive constant, or guard a column-derived n:\nSELECT max_n(value, GREATEST(n, 1)) FROM t; -- or WHERE n > 0","typeGuard":null,"tryCatchPattern":"try {\n    rs = stmt.executeQuery(\"SELECT max_n(v, \" + n + \") ...\");\n} catch (SQLException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"second argument of max_n/min_n must be positive\")) {\n        throw new IllegalArgumentException(\"n must be >= 1, got: \" + n, e);\n    }\n    throw e;\n}","preventionTips":["Always pass a positive literal n when possible","When n is computed, clamp with GREATEST(n, 1) and respect the max-values cap","Validate n >= 1 in application code before building the SQL","Note the heap is allocated on first row, so bad n fails on the first row of each group"],"tags":["aggregation","sql","invalid-argument"],"backgroundTag":"invalid-aggregation-argument","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}