{"record":{"id":"86f6790492cbd87f","repo":"SonarSource/sonarqube","slug":"failed-to-redirect-to-url","errorCode":null,"errorMessage":"Failed to redirect to ${url}","messagePattern":"Failed to redirect to (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":500,"severity":"warning","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubManifestCallbackFilter.java","lineNumber":250,"sourceCode":"\n  private String errorOn(String path, String message) {\n    return manifestGenerator.baseUrl() + path + \"&almManifestResult=error&almError=\" + encode(message);\n  }\n\n  // Auth-only flows have no DevOps setting key and belong on the GitHub authentication settings page.\n  private static String settingsPathFor(PendingManifest pending) {\n    return pending.setupDevops() ? SETTINGS_PATH : AUTH_SETTINGS_PATH;\n  }\n\n  private static String encode(String value) {\n    return URLEncoder.encode(value, StandardCharsets.UTF_8);\n  }\n\n  private static void redirect(HttpResponse response, String url) {\n    try {\n      response.sendRedirect(url);\n    } catch (IOException e) {\n      throw new IllegalStateException(\"Failed to redirect to \" + url, e);\n    }\n  }\n\n  @Override\n  public void init() {\n    // nothing to do\n  }\n\n  @Override\n  public void destroy() {\n    // nothing to do\n  }\n}\n","sourceCodeStart":232,"sourceCodeEnd":264,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GithubManifestCallbackFilter.java#L232-L264","documentation":"IllegalStateException from GithubManifestCallbackFilter.redirect: sendRedirect(url) threw an IOException while redirecting the user's browser during the GitHub App manifest callback. Indicates the client connection broke or the response was already committed.","triggerScenarios":"doFilter processing the manifest callback calls redirect(response, url) and the servlet container throws IOException on sendRedirect — client gone, connection reset, or response already committed.","commonSituations":"User navigated away mid-callback; short proxy timeouts; double-invocation of the callback filter.","solutions":["Retry the GitHub App configuration flow","Verify the callback URL is reachable and proxy timeouts are adequate","Check server logs for the underlying IOException and response-commit state"],"exampleFix":"// before\nredirect(response, url); // IOException -> IllegalStateException\n// after\ntry {\n  redirect(response, url);\n} catch (IllegalStateException e) {\n  logger.warn(\"Failed to redirect GitHub manifest callback\", e);\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  filterChain.doFilter(request, response);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Failed to redirect to \")) {\n    logger.warn(\"GitHub manifest callback redirect failed (client gone or response committed)\", e);\n  } else { throw e; }\n}","preventionTips":["Ensure the callback URL is reachable through proxies/firewalls","Do not write to the response before the filter redirects","Ask users to complete the GitHub App flow in one session"],"tags":["sonarqube","github-app","redirect","io"],"backgroundTag":"broken-pipe","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}