{"record":{"id":"957bf82d1dbd32d3","repo":"quarkusio/quarkus","slug":"cannot-mix-expressions","errorCode":null,"errorMessage":"Cannot mix expressions","messagePattern":"Cannot mix expressions","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/MicroProfileRestClientEnricher.java","lineNumber":1176,"sourceCode":"        private final String sourceMethod;\n\n        RestClientAnnotationExpressionParser(String input, String sourceMethod) {\n            this.input = Objects.requireNonNull(input);\n            this.sourceMethod = sourceMethod;\n        }\n\n        // this is a pretty naive implementation, but it suffices for what we are trying to do\n        List<Node> parse() {\n            int i = 0;\n            int configStart = -1;\n            int accessibleStart = -1;\n            int verbatimStart = -1;\n            List<Node> nodes = new ArrayList<>();\n            while (i < input.length()) {\n                char c = input.charAt(i);\n                if (c == '$') {\n                    if ((configStart != -1) || (accessibleStart != -1)) {\n                        throw new IllegalArgumentException(createEffectiveErrorMessage(\"Cannot mix expressions\"));\n                    }\n                    if (i == input.length() - 1) {\n                        throw new IllegalArgumentException(createEffectiveErrorMessage(\"Illegal end of expression\"));\n                    }\n                    if (input.charAt(i + 1) != '{') {\n                        throw new IllegalArgumentException(createEffectiveErrorMessage(\"'$' must always be followed by '{'\"));\n                    }\n                    if (verbatimStart != -1) {\n                        nodes.add(new Verbatim(input.substring(verbatimStart, i)));\n                    }\n                    i += 2;\n                    configStart = i;\n                    verbatimStart = -1;\n                } else if (c == '{') {\n                    if ((configStart != -1) || (accessibleStart != -1)) {\n                        throw new IllegalArgumentException(createEffectiveErrorMessage(\"Cannot mix expressions\"));\n                    }\n                    if (i == input.length() - 1) {","sourceCodeStart":1158,"sourceCodeEnd":1194,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-client/deployment/src/main/java/io/quarkus/rest/client/reactive/deployment/MicroProfileRestClientEnricher.java#L1158-L1194","documentation":"ClientHeaderParam values support one expression kind per position: ${config.property} for config lookups and {methodOrParam} for accessible/method references. Starting a ${...} expression while another config or accessible expression is still open means the value nests/mixes expression syntax, which the parser rejects with IllegalArgumentException at build time.","triggerScenarios":"A value like \"{methodA}${property}\" where an accessible expression was opened and not closed before the '$', or nested/malformed braces such as \"${a${b}}\".","commonSituations":"Hand-editing annotation values to combine a config placeholder with a method call in one expression, or typos leaving an expression unclosed before a '$' appears.","solutions":["Close each expression with } before starting another (e.g. \"{method}-${prop}\" not \"{method}${prop}\" without closing braces)","Remove the nested expression and use either a config lookup or a method reference, not both inside one expression","If you need concatenation, use separate expressions separated by literal text: \"{m}-${p}\""],"exampleFix":"// before\n@ClientHeaderParam(name=\"X\", value=\"${token{getId}}\")\n\n// after\n@ClientHeaderParam(name=\"X\", value=\"${token}-{getId}\")","handlingStrategy":"validation","validationCode":"// Reject nested/unclosed expressions before annotating\nString v = \"${token{getId}}\";\nint open = 0;\nfor (char c : v.toCharArray()) {\n    if (c == '{') open++;\n    if (c == '}') open--;\n    if (open > 1) throw new IllegalArgumentException(\"Nested expressions not allowed in \" + v);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Close every expression before starting the next","Concatenate expressions with literal separators instead of nesting","Keep annotation values simple; compose complex values in Java code"],"tags":["quarkus","rest-client","expression-parsing","clientheaderparam","syntax"],"backgroundTag":"expression-syntax-error","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}