dubinc/dub · error

An error occurred during authentication. Please try again.

Error message

An error occurred during authentication. Please try again.

What it means

This is the HTTP 500 response the callback server sends when anything inside the token-exchange/config-save block throws — most commonly a failure of oauthClient.authorizationCode.getToken (invalid or expired code, code_verifier/PKCE mismatch, redirect_uri mismatch) or an error writing the local config. The browser shows this message; the underlying exception is swallowed and the server exits.

Source

Thrown at packages/cli/src/api/callback.ts:72

      const configInfo: DubConfig = {
        access_token: accessToken.trim(),
        refresh_token: refreshToken,
        expires_at: expiresAt,
        domain: "dub.sh",
      };

      await setConfig(configInfo);
      spinner.succeed("Configuration completed");

      logger.info("");
      logger.info(chalk.green("Logged in successfully!"));
      logger.info("");

      res.writeHead(200, { "Content-Type": "text/html" });
      res.end("Authentication successful! You can close this window.");
    } catch (error) {
      res.writeHead(500, { "Content-Type": "text/html" });
      res.end("An error occurred during authentication. Please try again.");
    } finally {
      server.close();
      process.exit(0);
    }
  });

  setTimeout(() => {
    server.close();
    process.exit(0);
  }, 300000);

  server.listen(4587);
}

View on GitHub (pinned to f216b94a24)

Solutions

  1. Re-run the login command from scratch so a fresh authorization code and codeVerifier are generated — used/expired codes cannot be retried.
  2. Ensure the redirectUri passed to getToken exactly matches the one used in the authorize request and the OAuth app registration.
  3. Check write permissions on the CLI's config file location if login consistently fails after 'Verifying'.
  4. Enable verbose/debug logging or temporarily patch the catch to log `error` to see the true cause, since it is currently discarded.

Example fix

// before
} catch (error) {
  res.writeHead(500, { "Content-Type": "text/html" });
  res.end("An error occurred during authentication. Please try again.");
}
// after
} catch (error) {
  console.error("Auth failed:", error); // surface the real cause
  res.writeHead(500, { "Content-Type": "text/html" });
  res.end("An error occurred during authentication. Please try again.");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight checks before login
import { access, constants } from 'fs/promises';
await access(configPath, constants.W_OK); // throws early if config file isn't writable
// Also ensure redirectUri matches the one used in the authorize request
if (authorizeRedirectUri !== tokenExchangeRedirectUri) {
  throw new Error('redirect_uri mismatch between authorize and token requests');
}

Type guard

function isOAuthTokenError(e: unknown): e is Error {
  return e instanceof Error && /token|code|verifier|grant/i.test(e.message);
}

Try / catch

try {
  const tokens = await oauthClient.authorizationCode.getToken({ code, redirectUri, codeVerifier });
  await setConfig({ ...tokens, domain: 'dub.sh' });
} catch (error) {
  console.error('Token exchange or config save failed:', error);
  // Retry the whole login flow with a fresh code; a consumed code cannot be reused
}

Prevention

When it happens

Trigger: Exchanging the authorization code fails (code already used, expired, or PKCE codeVerifier/redirectUri don't match those used in the authorize request), or setConfig fails (e.g. unwritable config file/permissions).

Common situations: Refreshing the callback page so the code is consumed twice, restarting login without redoing the authorize step, clock skew invalidating tokens, or ~/.config (or equivalent) being read-only.

Understand the failure class

Related errors


AI-assisted analysis of dubinc/dub@f216b94a24 (2026-08-31). Data as JSON: /api/errors/1975aa23b8c620b9. Report an issue: GitHub.