{"record":{"id":"2e3e42219bb20c5c","repo":"antlr/antlr4","slug":"dependency-analysis-failed","errorCode":null,"errorMessage":"Dependency analysis failed.","messagePattern":"Dependency analysis failed\\.","errorType":"exception","errorClass":"MojoFailureException","httpStatus":null,"severity":"error","filePath":"antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java","lineNumber":290,"sourceCode":"        }\n\n\t\tlog.debug(\"Output directory base will be \" + outputDirectory.getAbsolutePath());\n\t\tlog.info(\"ANTLR 4: Processing source directory \" + sourceDirectory.getAbsolutePath());\n\t\tfor (List<String> args : argumentSets) {\n\t\t\ttry {\n\t\t\t\t// Create an instance of the ANTLR 4 build tool\n\t\t\t\ttool = new CustomTool(args.toArray(new String[0]));\n\t\t\t} catch (Exception e) {\n\t\t\t\tlog.error(\"The attempt to create the ANTLR 4 build tool failed, see exception report for details\", e);\n\t\t\t\tthrow new MojoFailureException(\"Error creating an instanceof the ANTLR tool.\", e);\n\t\t\t}\n\n            try {\n                dependencies.analyze(grammarFiles, importGrammarFiles, tool);\n            } catch (Exception e) {\n                log.error(\"Dependency analysis failed, see exception report for details\",\n                    e);\n                throw new MojoFailureException(\"Dependency analysis failed.\", e);\n            }\n\n\t\t\t// Set working directory for ANTLR to be the base source directory\n\t\t\ttool.inputDirectory = sourceDirectory;\n\n\t\t\ttool.processGrammarsOnCommandLine();\n\n\t\t\t// If any of the grammar files caused errors but did nto throw exceptions\n\t\t\t// then we should have accumulated errors in the counts\n\t\t\tif (tool.getNumErrors() > 0) {\n\t\t\t\tthrow new MojoExecutionException(\"ANTLR 4 caught \" + tool.getNumErrors() + \" build errors.\");\n\t\t\t}\n\t\t}\n\n        if (project != null) {\n            // Tell Maven that there are some new source files underneath the output directory.\n            addSourceRoot(this.getOutputDirectory());\n        }","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java#L272-L308","documentation":"The lowercase counterpart of the token check: a tag starting lowercase (e.g. <expr>) is treated as a rule reference; the matcher calls parser.getRuleIndex(tag) and receives -1 when the grammar has no such rule, then throws IllegalArgumentException with the unknown rule name. The rule must exist because the pattern will be matched as that rule's structure.","triggerScenarios":"Compiling a pattern with a rule tag that does not exist in the grammar (misspelling, renamed rule, or a rule from another grammar); passing the wrong patternRuleIndex context so the name lookup fails.","commonSituations":"Grammar refactors that rename rules without updating pattern strings embedded in application code; patterns shared across multiple grammars; typo-level mistakes like <ident> vs <identifier>.","solutions":["Verify the rule name against the generated parser's rule names (R.xxx constants or the grammar file).","Use the generated rule-index constants rather than strings where possible to keep names in sync.","Recompile patterns in tests whenever the grammar changes."],"exampleFix":"// before\nParseTreePattern p = m.compile(\"<ident> : <ID>\", R.stmt); // rule is 'identifier'\n\n// after\nParseTreePattern p = m.compile(\"<identifier> : <ID>\", R.stmt);","handlingStrategy":"try-catch","validationCode":"if (Character.isLowerCase(tag.charAt(0)) && parser.getRuleIndex(tag) == -1) {\n    throw new IllegalArgumentException(\"not a rule in this grammar: \" + tag);\n}","typeGuard":"boolean isKnownRule(Parser p, String tag) {\n    return Character.isLowerCase(tag.charAt(0)) && p.getRuleIndex(tag) != -1;\n}","tryCatchPattern":"try {\n    pattern = matcher.compile(patternText, ruleIndex);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unknown rule\")) {\n        // rule renamed in grammar: update pattern strings\n        reportStalePattern(patternText);\n    }\n    throw e;\n}","preventionTips":["Keep rule names in patterns synchronized with grammar renames via tests.","Prefer generated rule constants over hand-typed names where possible.","Compile patterns eagerly at startup, not lazily at first match."],"tags":["antlr","java","parse-tree-pattern","pattern-compile","grammar-mismatch"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}