{"record":{"id":"a9deeddc17cc07fa","repo":"apache/skywalking","slug":"auto-layer-rules-have-duplicate-name-name","errorCode":null,"errorMessage":"Auto-layer rules have duplicate name: {name}","messagePattern":"Auto-layer rules have duplicate name: (.+?)","errorType":"exception","errorClass":"ModuleStartException","httpStatus":null,"severity":"critical","filePath":"oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/LogFilterListener.java","lineNumber":252,"sourceCode":"         * {@code RecordSinkListener.Factory.<init>}, which calls {@code moduleManager.find()}\n         * and asserts the manager is past prepare.\n         *\n         * <p>Idempotent against re-entry within the same boot (the Factory only stays in\n         * its empty post-construct state until this fires once); calling it twice on the\n         * same instance is a programming error.\n         */\n        public void loadStaticRules() throws Exception {\n            final Map<Layer, Map<String, DSL>> initDsls = new HashMap<>();\n            final Map<String, DSL> initAutoDsls = new HashMap<>();\n            final List<LALConfig> configList = LALConfigs.load(analyzerConfig.getLalPath(), analyzerConfig.lalFiles())\n                                                         .stream()\n                                                         .flatMap(it -> it.getRules().stream())\n                                                         .collect(Collectors.toList());\n            for (final LALConfig c : configList) {\n                final CompiledLAL compiled = compile(c);\n                if (compiled.layer == null) {\n                    if (initAutoDsls.put(c.getName(), compiled.dsl) != null) {\n                        throw new ModuleStartException(\n                            \"Auto-layer rules have duplicate name: \" + c.getName());\n                    }\n                } else {\n                    final Map<String, DSL> layerDsls = initDsls.computeIfAbsent(compiled.layer, k -> new HashMap<>());\n                    if (layerDsls.put(c.getName(), compiled.dsl) != null) {\n                        throw new ModuleStartException(\n                            \"Layer \" + compiled.layer.name() + \" has already set \" + c.getName() + \" rule.\");\n                    }\n                }\n                // Publish per-rule debug holder into the dsl-debugging registry. sourceName, not\n                // sourcePath: both routes derive it through LALConfigs.stampSource, so a\n                // runtime-rule replace puts over the static binding without orphaning it.\n                LalStaticBindingHook.publish(c.getSourceName(), c.getName(), compiled.dsl.getExpression());\n            }\n            // Publish: readers from now on see the startup-complete registry.\n            this.dsls = initDsls;\n            this.autoDsls = initAutoDsls;\n        }","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/provider/log/listener/LogFilterListener.java#L234-L270","documentation":"Thrown during static rule load when two rules without an explicit layer (i.e. layer: auto rules) share the same name: loadStaticRules puts compiled DSLs into a name-keyed map (initAutoDsls) and a non-null previous value means a duplicate. Auto-layer rules are stored flat by name because they are selected by absence of service layer, not by a Layer key, making name uniqueness mandatory.","triggerScenarios":"Two LAL YAML files (or two entries in one file) both defining a rule named e.g. 'default' without a layer: declaration; copying a shipped rule file and keeping the name; a rule that omits layer: accidentally (omission means auto).","commonSituations":"Adding a custom rule file alongside default.yaml and reusing the name 'default'; merging rule sets from two teams; forgetting that omitting layer: puts the rule in the auto bucket.","solutions":["Rename one of the two rules so every auto-layer rule name is unique","If the rule belongs to a specific layer, add the layer: declaration — per-layer namespaces are separate","Remove the duplicate file from lalFiles if it was left in by accident"],"exampleFix":"# before: default.yaml and my-rules.yaml both contain\nruleName: default\n\n# after: my-rules.yaml\nruleName: my-custom-default","handlingStrategy":"validation","validationCode":"# Detect duplicate auto-layer rule names before deploy:\n#   grep -h '^ruleName:' lal/*.yaml | sort | uniq -d   # any output = future failure (layer-less rules)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give custom rules distinctive names; never reuse 'default'","Remember omitting layer: means auto — name accordingly","Add a CI duplicate-name check over the whole lal catalog"],"tags":["lal","log-analyzer","rules","duplicate","startup"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}