Error Codes

Complete reference for OAuth error codes and how to handle them in your application.

This reference covers all error codes you may encounter when using the Euler Stream OAuth system, organized by where they occur in the flow.

Authorization Errors

These errors are returned as query parameters when redirecting back to your redirect_uri:

https://yourapp.com/callback?error=ERROR_CODE&error_description=DESCRIPTION&state=YOUR_STATE

invalid_request

Cause: Missing or malformed required parameters.

error=invalid_request
error_description=Missing required parameter: client_id

Resolution: Ensure all required parameters are present:

  • client_id
  • redirect_uri
  • response_type (must be "code")
  • scope (at least one valid scope)

invalid_client

Cause: The client_id doesn't exist or has been deleted.

error=invalid_client
error_description=Unknown client_id

Resolution: Verify your client ID in the OAuth Dashboard.


invalid_scope

Cause: One or more requested scopes are invalid.

error=invalid_scope
error_description=Invalid scope: webcast:invalid_scope

Resolution: Check the Available Scopes and ensure you're using valid scope identifiers.


invalid_redirect_uri

Cause: The redirect_uri doesn't match any registered URIs for this client.

error=invalid_redirect_uri
error_description=Redirect URI not registered for this client

Resolution:

  1. Go to OAuth Dashboard → Your Client → Redirect URIs
  2. Add the exact URI you're using (origin + path must match exactly)
  3. Remember: HTTPS is required except for localhost

unsupported_response_type

Cause: The response_type parameter is not "code".

error=unsupported_response_type
error_description=Only response_type=code is supported

Resolution: Set response_type=code in your authorization URL.


access_denied

Cause: The user cancelled the authorization or denied permissions.

error=access_denied
error_description=User cancelled authorization

Resolution: This is a user action, not an error. Handle gracefully:

app.get('/auth/callback', (req, res) => {
  if (req.query.error === 'access_denied') {
    return res.redirect('/connect?message=authorization_cancelled');
  }
  // ... continue with normal flow
});

server_error

Cause: An unexpected server error occurred.

error=server_error
error_description=Internal server error

Resolution: Retry the authorization. If persistent, contact support.


Token Endpoint Errors

These errors are returned as JSON from the /tiktok/oauth/token endpoint:

{
  "error": "ERROR_CODE",
  "error_description": "Human-readable description"
}

invalid_grant

Cause: The authorization code is invalid, expired, or already used.

{
  "error": "invalid_grant",
  "error_description": "Authorization code expired or invalid"
}

Resolution:

  • Authorization codes expire after ~10 minutes
  • Codes can only be used once
  • Restart the OAuth flow if this occurs

invalid_client (Token)

Cause: Invalid client_id or client_secret.

{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}

Resolution: Verify your client ID and secret. If you regenerated your secret, update your application.


invalid_request (Token)

Cause: Missing required parameters in token request.

{
  "error": "invalid_request",
  "error_description": "Missing required parameter: grant_type"
}

Resolution: Ensure all required parameters are included:

For authorization code exchange:

  • grant_type=authorization_code
  • code
  • redirect_uri
  • client_id
  • client_secret

For token refresh:

  • grant_type=refresh_token
  • refresh_token
  • client_id
  • client_secret

expired_token

Cause: The refresh token has expired (after 30 days).

{
  "error": "expired_token",
  "error_description": "Refresh token has expired"
}

Resolution: User must complete the full authorization flow again. See Token Lifecycle.


revoked_token

Cause: The token has been revoked by the user or programmatically.

{
  "error": "revoked_token",
  "error_description": "Token has been revoked"
}

Resolution: User must re-authorize. The previous authorization is no longer valid.


API Request Errors

These errors occur when making API requests with an access token:

401 Unauthorized

HTTP Status: 401

Possible Causes:

  1. Missing or malformed Authorization header

    {
      "error": "unauthorized",
      "error_description": "Missing Authorization header"
    }
  2. Expired access token

    {
      "error": "token_expired",
      "error_description": "Access token has expired"
    }
  3. Invalid access token

    {
      "error": "invalid_token",
      "error_description": "Access token is invalid"
    }

Resolution:

async function makeRequest(endpoint: string, tokens: Tokens) {
  const response = await fetch(`https://tiktok.eulerstream.com${endpoint}`, {
    headers: {
      'Authorization': `Bearer ${tokens.accessToken}`,
    },
  });
 
  if (response.status === 401) {
    const error = await response.json();
 
    switch (error.error) {
      case 'token_expired':
        // Refresh the token and retry
        const newTokens = await refreshAccessToken(tokens.refreshToken);
        return makeRequest(endpoint, newTokens);
 
      case 'invalid_token':
      case 'revoked_token':
        // Token is invalid, need full re-authorization
        throw new ReauthorizationRequiredError();
 
      default:
        throw new Error(error.error_description);
    }
  }
 
  return response.json();
}

403 Forbidden - Insufficient Scope

HTTP Status: 403

{
  "error": "insufficient_scope",
  "error_description": "Token does not have required scope: webcast:rankings"
}

Resolution: The access token doesn't have the required scope for this endpoint. User must re-authorize with additional scopes.


Session Expired

HTTP Status: 401

{
  "error": "session_expired",
  "error_description": "Underlying TikTok session has expired"
}

Cause: The user's TikTok session (obtained via QR code) has expired or been invalidated. This can happen if:

  • User changed their TikTok password
  • User logged out of all devices on TikTok
  • TikTok invalidated the session for security reasons

Resolution:

  1. Revoke the existing OAuth tokens
  2. Prompt user to re-authorize via full OAuth flow
  3. Refreshing the token will NOT fix this—the underlying session is gone
if (error.error === 'session_expired') {
  // Revoke tokens (cleanup)
  await revokeToken(tokens.refreshToken, 'refresh_token');
 
  // Clear stored tokens
  await clearUserTokens(userId);
 
  // Notify user
  throw new SessionExpiredError(
    'Your TikTok connection has expired. Please reconnect your account.'
  );
}

Error Handling Best Practices

Comprehensive Error Handler

type OAuthError =
  | 'invalid_request'
  | 'invalid_client'
  | 'invalid_scope'
  | 'invalid_redirect_uri'
  | 'invalid_grant'
  | 'access_denied'
  | 'unsupported_response_type'
  | 'server_error'
  | 'expired_token'
  | 'revoked_token'
  | 'token_expired'
  | 'invalid_token'
  | 'insufficient_scope'
  | 'session_expired';
 
interface ErrorResponse {
  error: OAuthError;
  error_description?: string;
}
 
function handleOAuthError(error: ErrorResponse): never {
  switch (error.error) {
    // User action required
    case 'access_denied':
      throw new UserCancelledError();
 
    // Configuration errors (fix in dashboard)
    case 'invalid_client':
    case 'invalid_redirect_uri':
      throw new ConfigurationError(error.error_description);
 
    // Request errors (fix in code)
    case 'invalid_request':
    case 'invalid_scope':
    case 'unsupported_response_type':
      throw new InvalidRequestError(error.error_description);
 
    // Token errors (refresh or re-authorize)
    case 'invalid_grant':
    case 'expired_token':
    case 'revoked_token':
    case 'token_expired':
    case 'invalid_token':
    case 'session_expired':
      throw new ReauthorizationRequiredError(error.error_description);
 
    // Scope errors
    case 'insufficient_scope':
      throw new InsufficientScopeError(error.error_description);
 
    // Server errors (retry)
    case 'server_error':
    default:
      throw new ServerError(error.error_description);
  }
}

User-Friendly Error Messages

const ERROR_MESSAGES: Record<OAuthError, string> = {
  invalid_request: 'Something went wrong. Please try again.',
  invalid_client: 'Application configuration error. Please contact support.',
  invalid_scope: 'Invalid permissions requested.',
  invalid_redirect_uri: 'Application configuration error. Please contact support.',
  invalid_grant: 'Authorization expired. Please try connecting again.',
  access_denied: 'You cancelled the connection. No worries!',
  unsupported_response_type: 'Application configuration error. Please contact support.',
  server_error: 'Server error. Please try again later.',
  expired_token: 'Your connection expired. Please reconnect your TikTok account.',
  revoked_token: 'Your connection was disconnected. Please reconnect.',
  token_expired: 'Session expired. Please wait while we reconnect...',
  invalid_token: 'Connection error. Please reconnect your TikTok account.',
  insufficient_scope: 'Additional permissions required. Please reconnect.',
  session_expired: 'Your TikTok session expired. Please reconnect your account.',
};

Error Code Quick Reference

ErrorStageUser Action Required
invalid_requestAuth/TokenNo (fix code)
invalid_clientAuth/TokenNo (fix config)
invalid_scopeAuthNo (fix code)
invalid_redirect_uriAuthNo (fix config)
invalid_grantTokenYes (re-authorize)
access_deniedAuthYes (try again)
unsupported_response_typeAuthNo (fix code)
server_errorAnyNo (retry)
expired_tokenTokenYes (re-authorize)
revoked_tokenToken/APIYes (re-authorize)
token_expiredAPINo (refresh token)
invalid_tokenAPIYes (re-authorize)
insufficient_scopeAPIYes (re-authorize with more scopes)
session_expiredAPIYes (re-authorize)