{"record":{"id":"5ca0d69f66e6b49e","repo":"spring-projects/spring-security","slug":"code-and-errorcode-cannot-both-be-set","errorCode":null,"errorMessage":"code and errorCode cannot both be set","messagePattern":"code and errorCode cannot both be set","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponse.java","lineNumber":215,"sourceCode":"\t\t}\n\n\t\t/**\n\t\t * Sets the error uri.\n\t\t * @param errorUri the error uri\n\t\t * @return the {@link Builder}\n\t\t */\n\t\tpublic Builder errorUri(String errorUri) {\n\t\t\tthis.errorUri = errorUri;\n\t\t\treturn this;\n\t\t}\n\n\t\t/**\n\t\t * Builds a new {@link OAuth2AuthorizationResponse}.\n\t\t * @return a {@link OAuth2AuthorizationResponse}\n\t\t */\n\t\tpublic OAuth2AuthorizationResponse build() {\n\t\t\tif (StringUtils.hasText(this.code) && StringUtils.hasText(this.errorCode)) {\n\t\t\t\tthrow new IllegalArgumentException(\"code and errorCode cannot both be set\");\n\t\t\t}\n\t\t\tAssert.hasText(this.redirectUri, \"redirectUri cannot be empty\");\n\t\t\tOAuth2AuthorizationResponse authorizationResponse = new OAuth2AuthorizationResponse();\n\t\t\tauthorizationResponse.redirectUri = this.redirectUri;\n\t\t\tauthorizationResponse.state = this.state;\n\t\t\tif (StringUtils.hasText(this.code)) {\n\t\t\t\tauthorizationResponse.code = this.code;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tAssert.notNull(this.errorCode, \"errorCode cannot be null when code is not present\");\n\t\t\t\tAssert.hasText(this.errorCode, \"errorCode cannot be empty when code is not present\");\n\t\t\t\tauthorizationResponse.error = new OAuth2Error(this.errorCode, this.errorDescription, this.errorUri);\n\t\t\t}\n\t\t\treturn authorizationResponse;\n\t\t}\n\n\t}\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2AuthorizationResponse.java#L197-L233","documentation":"OAuth2AuthorizationResponse.Builder.build enforces the RFC 6749 distinction between a success authorization response (must carry code, must not carry error) and an error response (must carry errorCode). Supplying both is an invalid state, so it throws IllegalArgumentException.","triggerScenarios":"Programmatically building an OAuth2AuthorizationResponse where the builder's code(...) and errorCode(...) (or error param parsing) were both invoked — e.g. a custom authorization response converter or test fixture setting both fields from a redirect URL that oddly contains both parameters.","commonSituations":"Custom OAuth2AuthorizationRequestRepository/converters copying all query parameters into the builder; tests hand-building responses with leftover fields; provider redirects including both code and error in one redirect.","solutions":["Make the builder mutually exclusive: set code only when present, otherwise set error/errorDescription/errorUri","Sanitize the redirect URL parameters before building — prefer error fields when an error parameter exists","In custom converters, branch: if error param present use errorCode(...), else use code(...)"],"exampleFix":"// before\nbuilder.code(params.getFirst(\"code\")).errorCode(params.getFirst(\"error\"));\n// after\nif (StringUtils.hasText(params.getFirst(\"error\"))) {\n    builder.errorCode(params.getFirst(\"error\"));\n} else {\n    builder.code(params.getFirst(\"code\"));\n}","handlingStrategy":"validation","validationCode":"boolean hasCode = StringUtils.hasText(code);\nboolean hasError = StringUtils.hasText(errorCode);\nif (hasCode == hasError) {\n    throw new IllegalArgumentException(\"Exactly one of code or errorCode must be set\");\n}","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"code and errorCode\")) {\n        // rebuild response preferring the error branch\n    }\n}","preventionTips":["Branch builder calls on presence of the error parameter","Never copy both code and error query params into the builder","Sanitize redirect URL before building the response"],"tags":["oauth2","builder","validation","authorization-response"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}