{"record":{"id":"77e438a3f36dcc6e","repo":"apache/skywalking","slug":"unsupported-extension-parameter-type","errorCode":null,"errorMessage":"Unsupported extension parameter type: {}","messagePattern":"Unsupported extension parameter type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALMethodChainCodegen.java","lineNumber":238,"sourceCode":"                final List<String> values =\n                    ((MALExpressionModel.StringListArgument) arg).getValues();\n                sb.append(\"java.util.Arrays.asList(new String[]{\");\n                for (int i = 0; i < values.size(); i++) {\n                    if (i > 0) {\n                        sb.append(\", \");\n                    }\n                    sb.append('\"')\n                      .append(DslJavaSourceText.toLiteral(values.get(i)))\n                      .append('\"');\n                }\n                sb.append(\"})\");\n            } else {\n                throw new IllegalArgumentException(\n                    \"Expected list argument for extension function, got \"\n                        + arg.getClass().getSimpleName());\n            }\n        } else {\n            throw new IllegalArgumentException(\n                \"Unsupported extension parameter type: \"\n                    + expectedType.getName());\n        }\n    }\n\n    // ==================== Argument codegen ====================\n\n    /**\n     * Generates a method call argument with special handling for primitive double methods.\n     * For {@code .valueEqual(33)}: emits raw {@code 33.0}.\n     * For {@code .multiply(100)}: emits boxed {@code Long.valueOf(100L)}.\n     */\n    private void generateMethodCallArg(final StringBuilder sb,\n                                        final String var,\n                                        final MALExpressionModel.Argument arg,\n                                        final boolean primitiveDouble) {\n        if (primitiveDouble\n                && arg instanceof MALExpressionModel.ExprArgument) {","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALMethodChainCodegen.java#L220-L256","documentation":"Thrown by MALMethodChainCodegen.generateExtensionArg when the extension method's Java parameter type is none of String, double/float/long/int (or boxed variants), or List<String>. The codegen can only emit literals for that fixed type set, so any other parameter type (boolean, Object, custom class, Map, char, short...) on a @MALContextFunction method makes the rule uncompilable at the point the argument is generated.","triggerScenarios":"A @MALContextFunction method like 'f(SampleFamily, boolean flag)' or 'f(SampleFamily, Map<String,String> ctx)' invoked from a MAL expression — generateExtensionArg hits the final else branch for the unsupported type.","commonSituations":"Writing a new custom extension with a convenient boolean or enum flag parameter without knowing MAL's restricted parameter type table; reusing an existing Java utility method by just adding the annotation.","solutions":["Change the parameter type to one of the supported ones: String, double/Double, float/Float, long/Long, int/Integer, or List<String> (e.g. pass \"true\"/\"false\" as String and parse it)","Move richer configuration into the extension implementation itself (constructor, static config) instead of MAL arguments","Rebuild the extension jar and restart OAP so the corrected signature is registered"],"exampleFix":"// before\n@MALContextFunction\npublic static SampleFamily f(SampleFamily sf, boolean enabled) { ... }\n\n// after\n@MALContextFunction\npublic static SampleFamily f(SampleFamily sf, String enabled) {\n    boolean on = Boolean.parseBoolean(enabled);\n    ...\n}\n// rule: .myext::f(\"true\")","handlingStrategy":"validation","validationCode":"private static final Set<Class<?>> SUPPORTED = Set.of(String.class, double.class,\n    Double.class, float.class, Float.class, long.class, Long.class, int.class, Integer.class);\n\nvoid checkSignature(Method m) {\n    for (Class<?> p : m.getParameterTypes()) {\n        if (p != SampleFamily.class && !SUPPORTED.contains(p) && p != List.class) {\n            throw new IllegalArgumentException(\"Unsupported param type \" + p + \" on \" + m);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"this is raised at codegen; catch at DSL.parse level and report the extension class/method to its maintainer","preventionTips":["Restrict @MALContextFunction params to String, numerics, List<String> by design","Encode booleans/enums as String and parse inside the method"],"tags":["mal","extension","unsupported-type","spi"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}