{"record":{"id":"23a7ab37559dfeea","repo":"theonedev/onedev","slug":"malformed-user-match","errorCode":null,"errorMessage":"Malformed user match","messagePattern":"Malformed user match","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/util/usermatch/UserMatch.java","lineNumber":99,"sourceCode":"\t\t} else {\n\t\t\tthrow new ExplicitException(\"Unrecognized user match criteria\");\n\t\t}\n\t}\n\t\n\tpublic static UserMatch parse(@Nullable String userMatchString) {\n\t\tList<UserMatchCriteria> criterias = new ArrayList<>();\n\t\tList<UserMatchCriteria> exceptCriterias = new ArrayList<>();\n\t\t\n\t\tif (userMatchString != null) {\n\t\t\tCharStream is = CharStreams.fromString(userMatchString); \n\t\t\tUserMatchLexer lexer = new UserMatchLexer(is);\n\t\t\tlexer.removeErrorListeners();\n\t\t\tlexer.addErrorListener(new BaseErrorListener() {\n\n\t\t\t\t@Override\n\t\t\t\tpublic void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,\n\t\t\t\t\t\tint charPositionInLine, String msg, RecognitionException e) {\n\t\t\t\t\tthrow new RuntimeException(\"Malformed user match\");\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\t\t\tCommonTokenStream tokens = new CommonTokenStream(lexer);\n\t\t\tUserMatchParser parser = new UserMatchParser(tokens);\n\t\t\tparser.removeErrorListeners();\n\t\t\tparser.setErrorHandler(new BailErrorStrategy());\n\t\t\t\n\t\t\tUserMatchContext userMatchContext = parser.userMatch();\n\t\t\t\n\t\t\tfor (CriteriaContext criteriaContext: userMatchContext.criteria())\n\t\t\t\tcriterias.add(getUserMatchCriteria(criteriaContext));\n\t\t\t\n\t\t\tfor (ExceptCriteriaContext exceptCriteriaContext: userMatchContext.exceptCriteria()) {\n\t\t\t\texceptCriterias.add(getUserMatchCriteria(exceptCriteriaContext.criteria()));\n\t\t\t}\n\t\t}\n\t\t","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/util/usermatch/UserMatch.java#L81-L117","documentation":"UserMatch.parse builds an ANTLR lexer with a custom BaseErrorListener; any lexical/syntax failure in the user match string is rethrown as RuntimeException 'Malformed user match'. The expression violates the UserMatch grammar and cannot be tokenized into valid criteria.","triggerScenarios":"Parsing a user match string with unbalanced quotes/parentheses or invalid tokens, e.g. 'user:bob and (' or a stray semicolon.","commonSituations":"Hand-edited match settings; shell/YAML quoting stripping quotes; copy-paste introducing invisible characters.","solutions":["Correct the match expression syntax (quote names, balance parentheses)","Inspect the stored string for stripped quotes or stray characters from templating/shell","Catch RuntimeException around parse and show a syntax-error message before saving"],"exampleFix":"// before\nuserMatchString = \"user:bob and (\";\n// after\nuserMatchString = \"user:bob\";","handlingStrategy":"validation","validationCode":"try {\n    UserMatch.parse(matchString);\n} catch (RuntimeException e) {\n    throw new ExplicitException(\"Invalid user match: \" + matchString);\n}","typeGuard":null,"tryCatchPattern":"try {\n    UserMatch.parse(matchString);\n} catch (RuntimeException e) {\n    log.error(\"Malformed user match: {}\", matchString, e);\n}","preventionTips":["Keep match expressions simple and quote names with special chars","Watch for shell/YAML quoting stripping quotes","Parse-validate at settings-save time rather than at use time"],"tags":["parser","antlr","user-match","syntax"],"backgroundTag":"schema-validation-failed","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}