{"record":{"id":"8bb860b824b962ce","repo":"quarkusio/quarkus","slug":"mismatched-braces","errorCode":null,"errorMessage":"Mismatched braces: ","messagePattern":"Mismatched braces: ","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/attribute/ExchangeAttributeParser.java","lineNumber":142,"sourceCode":"                    state = 0;\n                    break;\n                }\n\n            }\n        }\n        switch (state) {\n            case 0:\n            case 1:\n            case 3:\n            case 5: {\n                if (pos != valueString.length()) {\n                    attributes.add(wrap(parseSingleToken(valueString.substring(pos))));\n                }\n                break;\n            }\n            case 2:\n            case 4: {\n                throw new RuntimeException(\"Mismatched braces: \" + valueString);\n            }\n        }\n        if (attributes.size() == 1) {\n            return attributes.get(0);\n        }\n        return new CompositeExchangeAttribute(attributes.toArray(new ExchangeAttribute[attributes.size()]));\n    }\n\n    public ExchangeAttribute parseSingleToken(final String token) {\n        for (final ExchangeAttributeBuilder builder : builders) {\n            ExchangeAttribute res = builder.build(token);\n            if (res != null) {\n                return res;\n            }\n        }\n        if (token.startsWith(\"%\")) {\n            log.errorf(\"Unknown token %s\", token);\n        }","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/attribute/ExchangeAttributeParser.java#L124-L160","documentation":"The exchange-attribute parser (used for access-log patterns etc.) found an unterminated %{...} group: the token state machine ended in state 2 or 4, meaning an opening brace was never closed, so it throws RuntimeException(\"Mismatched braces: \" + valueString).","triggerScenarios":"Configuring quarkus.http.access-log.pattern (or similar attribute string) with '%{' without the matching '}' — e.g. '%{Referer' instead of '%{i,Referer}'.","commonSituations":"Hand-edited access log patterns; patterns copied from Undertow docs with partial escapes; properties files where a closing brace was accidentally dropped or swallowed by tooling.","solutions":["Fix the pattern so every %{ has a matching }: e.g. %{i,Referer}i, %{q}s.","Validate the pattern by starting the app in dev mode — the parser fails fast at startup.","Use documented simple tokens (%h, %r, %b, %{i,Header}i) instead of hand-crafted brace groups.","If quoting issues in application.properties are stripping braces, quote the whole value or escape appropriately."],"exampleFix":"// before (application.properties)\nquarkus.http.access-log.pattern=%{Referer\n// after\nquarkus.http.access-log.pattern=%{i,Referer}i","handlingStrategy":"validation","validationCode":"static void validatePattern(String p) {\n    int depth = 0;\n    for (char c : p.toCharArray()) {\n        if (c == '%') continue;\n        if (c == '{') depth++;\n        if (c == '}') depth--;\n        if (depth < 0 || depth > 1) throw new IllegalArgumentException(\"bad pattern: \" + p);\n    }\n    if (depth != 0) throw new IllegalArgumentException(\"Mismatched braces in: \" + p);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate access-log patterns before startup (unit test or CI lint)","Copy tokens from Quarkus docs verbatim","Quote the full property value when it contains braces"],"tags":["configuration","access-log","parsing","quarkus"],"backgroundTag":"mismatched-braces-pattern","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"}