usebruno/bruno · error · Error

Access Token URL is required for OAuth2 client credentials…

Error message

Access Token URL is required for OAuth2 client credentials flow

What it means

Thrown by fetchTokenClientCredentials when the OAuth2Config.accessTokenUrl field is empty/undefined. The client-credentials grant needs a token endpoint to POST credentials to, so the helper refuses to build a request without one. It is a pre-flight validation guard, not a network error.

Solutions

  1. Set oauth2Config.accessTokenUrl to the full token endpoint URL (e.g. https://auth.example.com/oauth/token) before invoking the flow.
  2. If the URL comes from an env var, verify the variable is defined and non-empty at call time (console.log it in dev).
  3. Add a pre-call validation check (see validationCode) so the error surfaces in your code, not inside the helper.

Example fix

// before
const config = { grantType: 'client_credentials', clientId: 'abc', clientSecret: 'xyz' };
await getOAuth2AccessToken(config, tokenStore);

// after
const config = {
  grantType: 'client_credentials',
  accessTokenUrl: process.env.OAUTH_TOKEN_URL,
  clientId: 'abc',
  clientSecret: 'xyz'
};
await getOAuth2AccessToken(config, tokenStore);
Defensive patterns

Strategy: validation

Validate before calling

function validateClientCredentialsConfig(c) {
  if (!c.accessTokenUrl) throw new Error('accessTokenUrl missing for client_credentials flow');
  if (!c.clientId) throw new Error('clientId missing for client_credentials flow');
}
validateClientCredentialsConfig(config);

Type guard

function isClientCredentialsReady(c) {
  return c.grantType === 'client_credentials'
    && typeof c.accessTokenUrl === 'string' && c.accessTokenUrl.length > 0
    && typeof c.clientId === 'string' && c.clientId.length > 0;
}

Try / catch

try { await getOAuth2AccessToken(config, tokenStore); }
catch (e) { if (e.message.includes('Access Token URL is required')) { /* fill config */ } else throw e; }

Prevention

When it happens

Trigger: Calling getOAuth2AccessToken (or the Bruno auth pipeline) with grantType='client_credentials' but accessTokenUrl set to '', null, undefined, or omitted. This includes configs loaded from a collection where the token URL field was left blank by the user.

Common situations: User created an OAuth2 collection item but never filled the 'Access Token URL' field; env variable referencing the URL resolved to empty; config object assembled programmatically and the accessTokenUrl key was misspelled or destructured away.

Related errors


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/f86455f18f370a8f. Report an issue: GitHub.

Appendix: source

Thrown at packages/bruno-requests/src/auth/oauth2-helper.ts:122

    return data;
  }
};

/**
 * Fetches an OAuth2 token using client credentials grant
 */
const fetchTokenClientCredentials = async (oauth2Config: OAuth2Config, axiosInstance?: AxiosInstance) => {
  const {
    accessTokenUrl,
    clientId,
    clientSecret,
    scope,
    credentialsPlacement = 'basic_auth_header',
    additionalParameters
  } = oauth2Config;

  if (!accessTokenUrl) {
    throw new Error('Access Token URL is required for OAuth2 client credentials flow');
  }

  if (!clientId) {
    throw new Error('Client ID is required for OAuth2 client credentials flow');
  }

  const requestConfig: RequestConfig = {
    method: 'POST',
    url: accessTokenUrl,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Accept': 'application/json'
    },
    data: '',
    responseType: 'arraybuffer'
  };

  const data: ClientCredentialsData = {

View on GitHub (pinned to 9bdd81c7bd)