{"record":{"id":"06bd714c665f9db3","repo":"quarkusio/quarkus","slug":"illegal-end-of-expression","errorCode":null,"errorMessage":"Illegal end of expression","messagePattern":"Illegal end of expression","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":1179,"sourceCode":"            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) {\n                        throw new IllegalArgumentException(createEffectiveErrorMessage(\"Illegal end of expression\"));\n                    }\n                    if (verbatimStart != -1) {","sourceCodeStart":1161,"sourceCodeEnd":1197,"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#L1161-L1197","documentation":"The parser rejects a '$' at the very end of a ClientHeaderParam value because ${ requires a property name and a closing brace; a trailing '$' can never form a valid expression. It fails fast at build time with IllegalArgumentException wrapped with the offending input.","triggerScenarios":"Annotation value ending with a dangling '$', e.g. @ClientHeaderParam(name=\"X\", value=\"apikey$\") — often after accidental truncation or an intended literal '$' unescaped.","commonSituations":"Copy-paste truncation of long header values, or attempting to embed a literal dollar sign (e.g. currency) at the end of a header value.","solutions":["Complete the expression: replace trailing '$' with a full ${property} form","Remove the stray '$' if it was accidental","If a literal '$' is needed as verbatim text, ensure it is not the last character or restructure (the naive parser treats a lone '$' mid-text followed by '{' as an expression start; a trailing '$' is always invalid)"],"exampleFix":"// before\n@ClientHeaderParam(name=\"X-Price\", value=\"100$\")\n\n// after\n@ClientHeaderParam(name=\"X-Price\", value=\"USD 100\")","handlingStrategy":"validation","validationCode":"String v = \"apikey$\";\nif (v.trim().endsWith(\"$\")) {\n    throw new IllegalArgumentException(\"ClientHeaderParam value cannot end with a bare '$'\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never end header values with a bare '$'","Always complete ${...} expressions with property name and closing brace","Avoid raw currency symbols in annotation values; compute them in provider methods"],"tags":["quarkus","rest-client","expression-parsing","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-12T22:17:10.623Z"}