{"record":{"id":"4bef064699c14507","repo":"oracle/graal","slug":"directed-inlining-rule-must-have-non-empty-caller","errorCode":null,"errorMessage":"Directed inlining rule must have non-empty caller and callee filters: {ruleSpec}","messagePattern":"Directed inlining rule must have non-empty caller and callee filters: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/DirectedInliningRules.java","lineNumber":297,"sourceCode":"    }\n\n    private static IllegalArgumentException invalidCommand(Path commandFile, int lineNumber, String commandLine) {\n        return new IllegalArgumentException(commandFile + \":\" + lineNumber +\n                        \": Directed inlining command must have the form 'inline <rule>' or 'dontinline <rule>': \" + commandLine);\n    }\n\n    private static Rule parseRule(String ruleSpec) {\n        ArrayList<String> components = splitTopLevel(ruleSpec, EDGE_SEPARATOR);\n        if (components.size() < 2) {\n            throw invalidRule(ruleSpec);\n        }\n\n        ComponentFilter[] callerFilters = new ComponentFilter[components.size() - 1];\n        int[] callerBcis = new int[callerFilters.length];\n        for (int i = 0; i < callerFilters.length; i++) {\n            String callerSpec = components.get(i).trim();\n            if (callerSpec.isEmpty()) {\n                throw new IllegalArgumentException(\"Directed inlining rule must have non-empty caller and callee filters: \" + ruleSpec);\n            }\n            ParsedMethodSpec caller = parseMethodSpec(callerSpec, i == 0 ? \"root\" : \"inlined caller\", ruleSpec);\n            if (i == 0) {\n                callerFilters[i] = new ComponentFilter(parseSinglePositiveMethodFilter(caller.methodSpec(), \"root\", ruleSpec), ReceiverTypeFilter.EMPTY_ARRAY);\n            } else {\n                ParsedCalleeSpec callerTarget = parseCalleeSpec(caller.methodSpec(), ruleSpec);\n                callerFilters[i] = new ComponentFilter(parseSinglePositiveMethodFilter(callerTarget.methodSpec(), \"inlined caller\", ruleSpec), callerTarget.receiverTypes());\n            }\n            callerBcis[i] = caller.bci();\n        }\n\n        String calleeSpec = components.get(components.size() - 1).trim();\n        if (calleeSpec.isEmpty()) {\n            throw new IllegalArgumentException(\"Directed inlining rule must have non-empty caller and callee filters: \" + ruleSpec);\n        }\n\n        ParsedCalleeSpec callee = parseCalleeSpec(calleeSpec, ruleSpec);\n","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/inlining/DirectedInliningRules.java#L279-L315","documentation":"DirectedInliningRules.parseRule (DirectedInliningRules.java:297) splits a rule on the caller->callee edge separator and requires every caller component to be non-empty. This error fires when an intermediate caller component (not the last/callee position) trims to an empty string, e.g., a doubled separator 'A::m -> -> B::n'.","triggerScenarios":"A rule in the directed inlining rules file with an empty caller segment between edge separators, or a leading separator making the first caller empty.","commonSituations":"Typos with duplicated '->'; rules edited to remove a middle callsite but leaving the separator; whitespace-only segments.","solutions":["Fix the rule so each caller segment between separators names a method (class.method or class::* form)","Remove accidental doubled separators or leading/trailing separators","Consult EXPECTED_RULE_FORMAT in the class docs for the exact grammar"],"exampleFix":"# before\ninline : com.foo.A.f -> -> com.bar.B.g\n\n# after\ninline : com.foo.A.f -> com.bar.B.g","handlingStrategy":"validation","validationCode":"static void lintRule(String rule) {\n    for (String comp : rule.split(\"->\")) {\n        if (comp.trim().isEmpty() && !rule.trim().endsWith(comp.trim())) throw new IllegalArgumentException(\"empty caller segment: \" + rule);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never leave doubled '->' separators when editing rules","Generate rules programmatically instead of hand-editing when possible"],"tags":["graal","inlining","parsing","rules"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}