{"record":{"id":"cd7c81787be5e4ff","repo":"apache/skywalking","slug":"one-of-service-instance-or-endpoint-sho","errorCode":null,"errorMessage":"{}: one of service(), instance() or endpoint() should be invoked","messagePattern":"(.+?): one of service\\(\\), instance\\(\\) or endpoint\\(\\) should be invoked","errorType":"exception","errorClass":"ExpressionParsingException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/dsl/Expression.java","lineNumber":71,"sourceCode":"    }\n\n    /**\n     * Returns the per-rule capture binding the compiled rule carries. The\n     * {@code Analyzer.doAnalysis} hand-written probes read it once per ingest\n     * pass and then gate-guard {@code MALDebug.captureXxx(...)} calls on\n     * the holder's volatile {@code gate} field.\n     */\n    public GateHolder debugHolder() {\n        return expression.debugHolder();\n    }\n\n    /**\n     * Returns compile-time metadata extracted from the expression AST.\n     */\n    public ExpressionMetadata parse() {\n        final ExpressionMetadata metadata = expression.metadata();\n        if (metadata.getScopeType() == null) {\n            throw new ExpressionParsingException(\n                literal + \": one of service(), instance() or endpoint() should be invoked\");\n        }\n        if (log.isDebugEnabled()) {\n            log.debug(\"\\\"{}\\\" is parsed\", literal);\n        }\n        return metadata;\n    }\n\n    /**\n     * Run the expression with a data map.\n     *\n     * @param sampleFamilies a data map includes all of candidates to be analysis.\n     * @return The result of execution.\n     */\n    public Result run(final Map<String, SampleFamily> sampleFamilies) {\n        try {\n            for (final SampleFamily s : sampleFamilies.values()) {\n                if (s != SampleFamily.EMPTY) {","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/dsl/Expression.java#L53-L89","documentation":"Thrown by Expression.parse() in the MAL (Meter Analysis Language) v2 analyzer when the compiled expression's metadata has a null scope type. In MAL every metric expression must terminate in exactly one scope function — service(), instance() or endpoint() — which tells the OAP which level the aggregated metric belongs to. Without it the analyzer cannot build the persistence/source pipeline for the metric.","triggerScenarios":"A MAL rule (YAML meter-analyzer config) whose 'exp' field is a valid expression but is missing the trailing scope call, e.g. 'exp: http_requests_total.sum(['service']).rate('PT1M')' without '.service()'. Also triggered when the scope call is applied to a sub-expression in a way the compiler drops (e.g. inside a function argument rather than at the top level), so the AST root never carries a scopeType.","commonSituations":"Writing new MAL rules by copying PromQL and forgetting the SkyWalking-specific scope decorator; refactoring an expression and accidentally moving service() inside an aggregation argument; enabling a custom rule (meter-analyzer-config) that was never compiled before and fails at OAP startup.","solutions":["Add exactly one scope function at the end of the metric expression: .service(), .instance() or .endpoint(), matching which entity the metric should be attributed to","Check that the scope call wraps the whole expression, not an inner argument: use (a + b).service(), not a.service(...) + b","Validate the rule file with a small test that calls new Expression(literal).parse() (the analyzer's own unit-test pattern) before deploying to OAP","Confirm only one scope decorator appears; multiple scope calls on the same expression are also rejected upstream"],"exampleFix":"# before\nexp: http_success_request.sum(['service']).rate('PT1M')\n# after\nexp: http_success_request.sum(['service']).rate('PT1M').service()","handlingStrategy":"validation","validationCode":"import org.apache.skywalking.oap.meter.analyzer.v2.dsl.Expression;\n\nvoid validateMalExpression(String literal) {\n    Expression e = Expression.compile(literal); // or per API: new Expression(literal)\n    e.parse(); // throws ExpressionParsingException if scopeType is null\n}","typeGuard":null,"tryCatchPattern":"catch (ExpressionParsingException e) { log.error(\"MAL rule rejected, add .service()/.instance()/.endpoint(): {}\", e.getMessage()); }","preventionTips":["Always end MAL metric expressions with exactly one scope decorator","Unit-test each new MAL rule by compiling and calling parse() in CI","Keep a lint checklist for rule reviews: metricName, exp, filter, scope function"],"tags":["mal","dsl","meter-analyzer","oap","rule-config"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}