bitwarden/server · error · BadRequestException
Invalid response from Slack.
Error message
Invalid response from Slack.
What it means
Thrown during the Slack OAuth callback when slackService.ObtainTokenViaOAuth returns null or empty after exchanging the authorization code. This means the token exchange with Slack's API failed — the code was invalid/expired, Slack returned an error, or the network request failed. BadRequestException returns HTTP 400.
Source
Thrown at src/Api/Dirt/Controllers/SlackIntegrationController.cs:116
throw new NotFoundException();
}
// Fetch token from Slack and store to DB
string? callbackUrl = Url.RouteUrl(
routeName: "SlackIntegration_Create",
values: null,
protocol: currentContext.HttpContext.Request.Scheme,
host: currentContext.HttpContext.Request.Host.ToUriComponent()
);
if (string.IsNullOrEmpty(callbackUrl))
{
throw new BadRequestException("Unable to build callback Url");
}
var token = await slackService.ObtainTokenViaOAuth(code, callbackUrl);
if (string.IsNullOrEmpty(token))
{
throw new BadRequestException("Invalid response from Slack.");
}
integration.Configuration = JsonSerializer.Serialize(new SlackIntegration(token));
await integrationRepository.UpsertAsync(integration);
var location = $"/organizations/{integration.OrganizationId}/integrations/{integration.Id}";
return Created(location, new OrganizationIntegrationResponseModel(integration));
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Ensure the authorization code is exchanged immediately after receipt (Slack codes expire quickly).
- Verify the Slack app's redirect URI in the Slack dashboard exactly matches the deployed callback URL.
- Check Slack client_id/client_secret configuration in the server.
- Add idempotency handling so a retried callback doesn't re-consume an already-used code.
Example fix
// before
var token = await slackService.ObtainTokenViaOAuth(code, callbackUrl);
if (string.IsNullOrEmpty(token)) throw new BadRequestException("Invalid response from Slack.");
// after — log the actual Slack error for diagnosis
var (token, error) = await slackService.ObtainTokenViaOAuthDetailed(code, callbackUrl);
if (string.IsNullOrEmpty(token))
{
_logger.LogError("Slack token exchange failed: {Error}", error);
throw new BadRequestException($"Slack OAuth failed: {error}");
} Defensive patterns
Strategy: retry
Validate before calling
// Cannot validate Slack's response client-side, but can pre-check config
if (string.IsNullOrWhiteSpace(_config["Slack:ClientId"]) ||
string.IsNullOrWhiteSpace(_config["Slack:ClientSecret"]))
throw new InvalidOperationException("Slack OAuth credentials not configured."); Type guard
public static bool SlackCredentialsConfigured(IConfiguration config) =>
!string.IsNullOrEmpty(config["Slack:ClientId"]) &&
!string.IsNullOrEmpty(config["Slack:ClientSecret"]); Try / catch
int attempts = 0;
string? token = null;
while (attempts < 3 && string.IsNullOrEmpty(token))
{
try { token = await _slackService.ObtainTokenViaOAuth(code, callbackUrl); }
catch (Exception ex) when (attempts < 2) { _logger.LogWarning("Slack token attempt {N} failed: {Ex}", attempts, ex.Message); }
attempts++;
}
if (string.IsNullOrEmpty(token))
return BadRequest("Slack OAuth token exchange failed. Please retry the authorization flow."); Prevention
- Exchange the authorization code immediately — Slack codes expire within minutes.
- Register the exact callback URL in the Slack app settings to avoid redirect mismatch.
- Keep Slack client_id/client_secret in secure configuration, not in source.
When it happens
Trigger: OAuth callback with a stale, already-used, or invalid authorization code; Slack API temporarily unavailable during token exchange; redirect URL mismatch between the code request and the token exchange request (Slack validates exact match); client_id/client_secret misconfiguration.
Common situations: User takes too long to authorize so the code expires; double-clicking the authorize button consumes the code twice; Slack app credentials rotated but not updated in server config; network blip during the server-to-Slack token call; redirect URI registered in Slack app settings doesn't match the deployed callback URL.
Related errors
- Invalid response from Teams.
- Unable to build callback Url
- There already exists a Slack integration for this organizati
- Unable to build callback Url
- There already exists a Teams integration for this organizati
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/a814262ca89a3182.
Report an issue: GitHub.