{"record":{"id":"7554fbf901e30296","repo":"quarkusio/quarkus","slug":"path-parameter-may-not-be-followed-by-an-alphanum","errorCode":null,"errorMessage":"Path parameter  may not be followed by an alphanumeric character or underscore: ","messagePattern":"Path parameter  may not be followed by an alphanumeric character or underscore: ","errorType":"validation","errorClass":"WebSocketServerException","httpStatus":null,"severity":"error","filePath":"extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java","lineNumber":1040,"sourceCode":"            path = \"/\" + path;\n        }\n        return prefix + path;\n    }\n\n    static String getPath(String path) {\n        if (path.isEmpty()) {\n            return path;\n        }\n        StringBuilder sb = new StringBuilder();\n        Matcher m = PATH_PARAM_PATTERN.matcher(path);\n        while (m.find()) {\n            // Replace {foo} with :foo\n            String match = m.group();\n            int end = m.end();\n            if (end < path.length()) {\n                char nextChar = path.charAt(end);\n                if (Character.isAlphabetic(nextChar) || Character.isDigit(nextChar) || nextChar == '_') {\n                    throw new WebSocketServerException(\"Path parameter \" + match\n                            + \" may not be followed by an alphanumeric character or underscore: \" + path);\n                }\n            }\n            m.appendReplacement(sb, \":\" + match.subSequence(1, match.length() - 1));\n        }\n        m.appendTail(sb);\n        return path.startsWith(\"/\") ? sb.toString() : \"/\" + sb.toString();\n    }\n\n    public static String getOriginalPath(String path) {\n        StringBuilder sb = new StringBuilder();\n        Matcher m = TRANSLATED_PATH_PARAM_PATTERN.matcher(path);\n        while (m.find()) {\n            // Replace :foo with {foo}\n            String match = m.group();\n            m.appendReplacement(sb, \"{\" + match.subSequence(1, match.length()) + \"}\");\n        }\n        m.appendTail(sb);","sourceCodeStart":1022,"sourceCodeEnd":1058,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java#L1022-L1058","documentation":"WebSocket path templates use {param} placeholders which are rewritten to :param routing patterns. A placeholder may not be immediately followed by a letter, digit, or underscore, because the generated pattern would become ambiguous/unparseable. The build fails with WebSocketServerException naming the offending path.","triggerScenarios":"Declaring @WebSocket(path = ...) where a '{param}' segment is directly followed by an alphanumeric or '_' character, e.g. path = \"/users/{id}x\" or \"/files/{name}_backup\". The regex-match loop in path conversion detects the bad following character.","commonSituations":"Appending a literal suffix right after a placeholder without a separator; typos when writing REST-like paths; converting existing route definitions from frameworks with different path syntax.","solutions":["Insert a separator between the placeholder and any following literal: '/', '-', or '.' (e.g. {id}/x, {id}-detail).","Rewrite the path so placeholders occupy whole segments.","If a literal must touch the parameter, move the literal into the handler or use a different path design."],"exampleFix":"// before\n@WebSocket(path = \"/users/{id}x\")\n// after\n@WebSocket(path = \"/users/{id}/x\")","handlingStrategy":"validation","validationCode":"// Validate the path before annotating: no '{...}' followed by [A-Za-z0-9_]\nstatic boolean isValidWsPath(String path) {\n    return path == null || !java.util.regex.Pattern.compile(\"\\\\{[^}]+\\\\}[A-Za-z0-9_]\").matcher(path).find();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep each {param} as a whole path segment","Follow placeholders only with '/', '-', or '.' literals","Write a unit test asserting endpoint path patterns","Beware translating path syntax from frameworks allowing {id}suffix"],"tags":["quarkus","websockets-next","path","validation","build-time"],"backgroundTag":"invalid-path-template","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"}