{"record":{"id":"29249e65813211ce","repo":"apache/skywalking","slug":"has-been-defined-but-calculate-function-or-are","errorCode":null,"errorMessage":"{} has been defined, but calculate function or/are scope type is/are different.","messagePattern":"(.+?) has been defined, but calculate function or/are scope type is/are different\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java","lineNumber":272,"sourceCode":"        // new MetricsStreamProcessor workers, and a new prototype that shadowed the old\n        // one in {@link #meterPrototypes} — a removeMetric by name could only tear down the\n        // latest generation, leaving prior workers + classloaders pinned forever. Match on\n        // scope + data type + function class; any of those differing is a genuine shape\n        // change and the existing IllegalArgumentException on the pool path fires below.\n        final MeterDefinition existingDefinition = meterPrototypes.get(metricsName);\n        if (existingDefinition != null\n            && existingDefinition.getScopeType() == type\n            && existingDefinition.getDataType().equals(dataType)\n            && existingDefinition.getMeterPrototype().getClass().getSuperclass() == meterFunction) {\n            log.debug(\"Metric {} already registered with matching shape; reusing existing \"\n                + \"Metrics class + workers (FILTER_ONLY re-apply path).\", metricsName);\n            return;\n        }\n        try {\n            CtClass existingMetric = pool.get(METER_CLASS_PACKAGE + className);\n            if (existingMetric.getSuperclass() != parentClass\n                || type != meterPrototypes.get(metricsName).getScopeType()) {\n                throw new IllegalArgumentException(\n                    metricsName + \" has been defined, but calculate function or/are scope type is/are different.\");\n            }\n            log.info(\"Metric {} is already defined, so skip the metric creation.\", metricsName);\n            return;\n        } catch (NotFoundException ignored) {\n            // proceed — class not yet defined in this pool\n        }\n        CtClass metricsClass = pool.makeClass(METER_CLASS_PACKAGE + className, parentClass);\n        try {\n            metricsClass.addConstructor(CtNewConstructor.make(\"public \" + className + \"() {}\", metricsClass));\n            metricsClass.addMethod(CtNewMethod.make(\n                \"public org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue createNew() {\"\n                    + \"    org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue meterVar = new \" + METER_CLASS_PACKAGE + className + \"();\"\n                    + \"    ((org.apache.skywalking.oap.server.core.analysis.meter.Meter)meterVar).initMeta(\\\"\" + metricsName + \"\\\", \" + type.getScopeId() + \");\"\n                    + \"    return meterVar;\"\n                    + \"}\",\n                metricsClass));\n        } catch (CannotCompileException e) {","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java#L254-L290","documentation":"MeterSystem keeps a pool-level check for already-generated metric classes: if a class named org.apache.skywalking.oap.server.core.analysis.meter.<FormattedName> already exists in the pool, it is only reusable when its superclass (the calc function) and the registered scope type are identical to the new request. Otherwise creation is rejected with this IllegalArgumentException — the metric name is a stable identity and its shape cannot silently change.","triggerScenarios":"Two MAL rules (or a rule re-applied after edit) declare the same metric name with different functions, e.g. avg then sum; the same metric name is declared with different ScopeType (Service vs Endpoint) in separate rules; an OAL metric and a MAL metric collide on the generated class name in the same pool.","commonSituations":"Hot-updating a MAL config where the operator changed the aggregation function or scope of an existing metric without an OAP restart; copy-pasting rules between otel-rules files and forgetting to rename the metric; mixing native meter-analyzer-config rules with otel-rules rules that reuse a metric name.","solutions":["Pick a new metric name for the new shape (e.g. endpoint_qps_avg vs endpoint_qps_sum) and update dashboards/queries accordingly","If the old shape must be replaced, remove it first via MeterSystem.removeMetric / rule hot-remove, or restart the OAP server so pools start clean","Audit all active MAL/LAL/OAL rules for duplicate metric names with differing function or scope declarations"],"exampleFix":"# before (two rules, same metric name, different function)\nendpoint_sla = avg(otel...http_server_duration);\nendpoint_sla = sum(otel...http_server_duration);\n\n# after\nendpoint_sla_avg = avg(otel...http_server_duration);\nendpoint_sla_sum = sum(otel...http_server_duration);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    meterSystem.create(name, func, type, dataType);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"has been defined\")) {\n        log.warn(\"Metric {} redefined with a different shape; rename or remove it first\", name);\n    }\n    throw e;\n}","preventionTips":["Treat metric names as immutable identities: function and scope are part of the contract","When editing a MAL rule's function or scope, change the metric name too","Run a CI lint over all MAL/LAL/OAL rule files that flags duplicate metric names with differing shapes"],"tags":["meter-system","mal","metric-naming","hot-reload","config"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}