{"record":{"id":"c4bf7f12fe8af60c","repo":"prestodb/presto","slug":"unsupported-state-type-combination-s-s","errorCode":null,"errorMessage":"Unsupported state type combination: (%s, %s)","messagePattern":"Unsupported state type combination: \\((.+?), (.+?)\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/operator/aggregation/minmaxby/TwoNullableValueStateMapping.java","lineNumber":80,"sourceCode":"                .put(ImmutableList.of(Block.class, Slice.class), BlockAndBlockPositionValueState.class)\n                .build();\n    }\n\n    public static Class<? extends AccumulatorState> getStateClass(Class<?> first, Class<?> second)\n    {\n        List<Class<?>> key = ImmutableList.of(first, second);\n        Class<? extends AccumulatorState> state = STATE_MAPPINGS.get(key);\n        checkArgument(state != null, \"Unsupported state type combination: (%s, %s)\", first.getName(), second.getName());\n        return state;\n    }\n\n    public static AccumulatorStateSerializer<?> getStateSerializer(Type firstType, Type secondType)\n    {\n        Class<?> firstJavaType = firstType.getJavaType();\n        Class<?> secondJavaType = secondType.getJavaType();\n\n        if (secondJavaType != Block.class && secondJavaType != Slice.class) {\n            throw new IllegalArgumentException(format(\"Unsupported state type combination: (%s, %s)\", firstJavaType.getName(), secondJavaType.getName()));\n        }\n        if (firstJavaType == boolean.class) {\n            return new BooleanAndBlockPositionStateSerializer(firstType, secondType);\n        }\n        if (firstJavaType == long.class) {\n            return new LongAndBlockPositionStateSerializer(firstType, secondType);\n        }\n        if (firstJavaType == double.class) {\n            return new DoubleAndBlockPositionStateSerializer(firstType, secondType);\n        }\n        if (firstJavaType == Slice.class) {\n            return new SliceAndBlockPositionStateSerializer(firstType, secondType);\n        }\n        if (firstJavaType == Block.class) {\n            return new BlockAndBlockPositionStateSerializer(firstType, secondType);\n        }\n        throw new IllegalArgumentException(format(\"Unsupported state type combination: (%s, %s)\", firstJavaType.getName(), secondJavaType.getName()));\n    }","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/operator/aggregation/minmaxby/TwoNullableValueStateMapping.java#L62-L98","documentation":"TwoNullableValueStateMapping.getStateSerializer selects an AccumulatorStateSerializer for aggregations over two nullable inputs based on the Java types of the two state types. The serializer factory only supports secondType whose Java type is Block or Slice; anything else (e.g. long, boolean, double) is unsupported and triggers an IllegalArgumentException before any type-specific branch runs.","triggerScenarios":"Invoking an aggregation built on TwoNullableValueStateMapping (e.g. variants of min_by/max_by with two nullable inputs) where the second type's getJavaType() is neither Block.class nor Slice.class.","commonSituations":"Registering/using a custom two-nullable-argument aggregation function with an unsupported second parameter type (a scalar like BIGINT or BOOLEAN as the second input); engine internals mismatching state serializers after a version upgrade.","solutions":["Ensure the second input to the aggregation is a complex (Block/Slice-backed) type, e.g. pass the key column as the second argument of min_by/max_by rather than a scalar state.","Check argument order — swapping the two arguments may put a supported type in position two.","If implementing a custom function, add a serializer branch or coerce the second type to a supported representation.","Verify the aggregation function registration matches the connector's supported signatures."],"exampleFix":"// before\nserializer = TwoNullableValueStateMapping.getStateSerializer(bigintType, bigintType); // unsupported second type\n// after\nserializer = TwoNullableValueStateMapping.getStateSerializer(bigintType, blockType); // second type must be Block/Slice-backed","handlingStrategy":"type-guard","validationCode":"-- Only invoke the aggregation when the second input is a complex (array/map/row) type\nSELECT typeof(key_col) FROM t LIMIT 1; -- must be array/map/row, not bigint/boolean","typeGuard":"boolean isSupportedSecondType(Type secondType) {\n    Class<?> j = secondType.getJavaType();\n    return j == Block.class || j == Slice.class;\n}","tryCatchPattern":null,"preventionTips":["Check argument order for two-nullable-input aggregations.","Verify function signatures before registering custom aggregations with this state mapping.","Document that secondType must be Block- or Slice-backed."],"tags":["aggregation","type-system","state-serializer","illegal-argument"],"backgroundTag":"unsupported-type-combination","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"}