{"record":{"id":"d56c81d52c1882fc","repo":"Budibase/budibase","slug":"oauth-config-id-could-not-be-found","errorCode":null,"errorMessage":"oAuth config ${id} could not be found","messagePattern":"oAuth config (.+?) could not be found","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/oauth2/utils.ts","lineNumber":108,"sourceCode":"}): Promise<{ value: string; ttl: number }> {\n  const resp = await fetchToken(config)\n  const jsonResponse = await resp.json()\n  if (!resp.ok) {\n    const message = jsonResponse.error_description ?? resp.statusText\n    throw new Error(`Error fetching oauth2 token: ${message}`)\n  }\n  const token = `${jsonResponse.token_type} ${jsonResponse.access_token}`\n  const ttl = jsonResponse.expires_in ?? -1\n  return { value: token, ttl }\n}\n\nexport async function getToken(id: string) {\n  const token = await cache.withCacheWithDynamicTTL(\n    cache.CacheKey.OAUTH2_TOKEN(id),\n    async () => {\n      const config = await get(id)\n      if (!config) {\n        throw new HTTPError(`oAuth config ${id} could not be found`, 400)\n      }\n      return fetchAndParseToken(config)\n    }\n  )\n\n  await trackUsage(id)\n  return token\n}\n\nexport async function getTokenFromConfig(\n  cacheKey: string,\n  config: {\n    url: string\n    clientId: string\n    clientSecret: string\n    method: OAuth2CredentialsMethod\n    grantType: OAuth2GrantType\n    scope?: string","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/oauth2/utils.ts#L90-L126","documentation":"getToken(id) loads the OAuth2 config by id from the workspace DB inside the token cache loader; if no config document exists it throws this 400 HTTPError. It guards the token-fetch path so requests referencing a deleted or unknown OAuth2 config fail fast with a clear message.","triggerScenarios":"Any caller of getToken (queries/auth headers/automation steps) supplying an oauth2 config id that does not exist in the workspace: the config was deleted after being referenced by a query/datasource, the id is misspelled, or it belongs to another app's workspace DB.","commonSituations":"Deleting an OAuth2 config that is still referenced by REST queries; exporting/importing apps without the config docs; hardcoding ids copied from another environment; caching layers holding references to purged configs.","solutions":["Restore or recreate the OAuth2 config with that id in the workspace","Update the referencing query/datasource to a valid config id","Verify the workspace context — the id must exist in the app being served","Run sdk.workspace.oauth2.fetch() to list valid ids"],"exampleFix":"// before\nconst headers = await getAuthHeaders('oauth2_cfg_wrongid')\n// after\nconst configs = await sdk.workspace.oauth2.fetch()\nconst config = configs.find(c => c.name === 'my-provider')\nif (!config) throw new Error('Configure the OAuth2 provider first')\nconst headers = await getAuthHeaders(config._id)","handlingStrategy":"validation","validationCode":"const configs = await sdk.workspace.oauth2.fetch()\nconst config = configs.find(c => c._id === id)\nif (!config) throw new Error(`OAuth2 config '${id}' is not configured in this app`)","typeGuard":"function hasOAuthConfig(\n  c: OAuth2Config | undefined\n): c is OAuth2Config {\n  return !!c && typeof c._id === \"string\"\n}","tryCatchPattern":"try {\n  const headers = await getAuthHeaders(id)\n} catch (e) {\n  if (e instanceof HTTPError && e.status === 400 && /could not be found/.test(e.message)) {\n    // fall back to unauthenticated request or prompt user to configure OAuth2\n  } else throw e\n}","preventionTips":["Reference configs by name resolved at runtime instead of hardcoding ids","Delete or re-point queries that reference configs before removing the config","Keep exports/imports of apps including their oauth2 config docs"],"tags":["oauth2","not-found","configuration"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}