{"record":{"id":"147ce35b734a647c","repo":"usebruno/bruno","slug":"client-id-is-required-for-oauth2-password-credenti","errorCode":null,"errorMessage":"Client ID is required for OAuth2 password credentials flow","messagePattern":"Client ID is required for OAuth2 password credentials flow","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-requests/src/auth/oauth2-helper.ts","lineNumber":227,"sourceCode":"    scope,\n    credentialsPlacement = 'basic_auth_header',\n    additionalParameters\n  } = oauth2Config;\n\n  if (!accessTokenUrl) {\n    throw new Error('Access Token URL is required for OAuth2 password credentials flow');\n  }\n\n  if (!username) {\n    throw new Error('Username is required for OAuth2 password credentials flow');\n  }\n\n  if (!password) {\n    throw new Error('Password is required for OAuth2 password credentials flow');\n  }\n\n  if (!clientId) {\n    throw new Error('Client ID is required for OAuth2 password credentials flow');\n  }\n\n  const requestConfig: RequestConfig = {\n    method: 'POST',\n    url: accessTokenUrl,\n    headers: {\n      'Content-Type': 'application/x-www-form-urlencoded',\n      'Accept': 'application/json'\n    },\n    data: '',\n    responseType: 'arraybuffer'\n  };\n\n  const data: PasswordGrantData = {\n    grant_type: 'password',\n    username,\n    password\n  };","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-requests/src/auth/oauth2-helper.ts#L209-L245","documentation":"Thrown by fetchTokenPassword when oauth2Config.clientId is falsy. Even the password grant requires a client_id so the authorization server can identify the requesting application; the helper validates it after username/password checks.","triggerScenarios":"getOAuth2AccessToken with grantType='password', valid accessTokenUrl/username/password, but clientId empty/undefined.","commonSituations":"Public-client setup where the developer assumed client_id is optional; the clientId env var missing in production; config assembled from multiple sources and the clientId branch was skipped.","solutions":["Provide a non-empty clientId for the application registered with the authorization server.","Verify the client registration includes the password grant as an allowed flow.","Load clientId from a single source of truth and assert it is set at startup."],"exampleFix":"// before\nconst config = { grantType: 'password', accessTokenUrl: url, username: user, password: pass };\n\n// after\nconst config = {\n  grantType: 'password',\n  accessTokenUrl: url,\n  username: user,\n  password: pass,\n  clientId: process.env.OAUTH_CLIENT_ID\n};","handlingStrategy":"validation","validationCode":"if (!config.clientId) throw new Error('clientId required even for password grant');","typeGuard":"function hasClientIdForPassword(c) { return typeof c.clientId === 'string' && c.clientId.length > 0; }","tryCatchPattern":"try { await getOAuth2AccessToken(config, tokenStore); }\ncatch (e) { if (e.message.includes('Client ID is required for OAuth2 password')) { /* set clientId */ } else throw e; }","preventionTips":["Register the client for the password grant at the authorization server.","Treat clientId as mandatory for every grant this helper supports.","Centralize clientId in one config constant."],"tags":["oauth2","validation","configuration","password-grant","secrets"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}