{"record":{"id":"8dfcd0a145ff91a8","repo":"apache/skywalking","slug":"unclosed-interpolation-in-s","errorCode":null,"errorMessage":"Unclosed interpolation in: {s}","messagePattern":"Unclosed interpolation in: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/compiler/LALScriptParser.java","lineNumber":1033,"sourceCode":"            }\n            // Literal text before ${\n            if (start > pos) {\n                parts.add(InterpolationPart.ofLiteral(s.substring(pos, start)));\n            }\n            // Find matching closing brace, respecting nesting\n            int depth = 1;\n            int i = start + 2;\n            while (i < s.length() && depth > 0) {\n                final char c = s.charAt(i);\n                if (c == '{') {\n                    depth++;\n                } else if (c == '}') {\n                    depth--;\n                }\n                i++;\n            }\n            if (depth != 0) {\n                throw new IllegalArgumentException(\n                    \"Unclosed interpolation in: \" + s);\n            }\n            final String expr = s.substring(start + 2, i - 1);\n            // Parse the expression as a valueAccess through ANTLR\n            parts.add(InterpolationPart.ofExpression(parseValueAccessExpr(expr)));\n            pos = i;\n        }\n        return parts;\n    }\n\n    /**\n     * Parses a standalone valueAccess expression string by wrapping it in\n     * a minimal LAL script and extracting the parsed ValueAccess.\n     */\n    private static ValueAccess parseValueAccessExpr(final String expr) {\n        // Wrap in: filter { if (EXPR) { sink {} } }\n        // The expression becomes a condition, parsed as ExprCondition\n        // whose ValueAccess is what we want.","sourceCodeStart":1015,"sourceCodeEnd":1051,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/compiler/LALScriptParser.java#L1015-L1051","documentation":"Same unknown-function failure as the 3-arg create, but from the extended MeterSystem.create(metricsName, functionName, ScopeType, ClassPool, ClassLoader, StorageManipulationOpt) overload used by the MAL runtime compiler. The functionName lookup in functionRegister fails for identical reasons: no @MeterFunction class registered under that name.","triggerScenarios":"The MAL analyzer compiles a rule and calls this overload with a function name absent from the register — typo'd name, custom function not on the classpath, or name drift after upgrading OAP where a function was renamed.","commonSituations":"Loading meter-analyzer-config YAML at boot or via dynamic configuration; custom MAL functions packaged outside the scanned org.apache.skywalking packages; mixing rule versions with the OAP binary.","solutions":["Fix the function name in the MAL config to match an existing @MeterFunction functionName","Ensure custom function classes live under org.apache.skywalking and are on the OAP classpath","Check the OAP log at startup — the scan-based register is built in the MeterSystem constructor; load errors there explain empty entries"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) { throw new RuntimeException(\"MAL compilation failed for function '\" + functionName + \"'\", e); }","preventionTips":["Validate MAL configs before deploying (OAP dry-run or linter)","Deploy custom @MeterFunction jars under org.apache.skywalking packages"],"tags":["skywalking","oap","meter","mal","configuration"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}