{"record":{"id":"1593fe8678a537bf","repo":"ToolJet/ToolJet","slug":"google-oauth-clientid-oauth-type-tooljet","errorCode":null,"errorMessage":"Google OAuth \"clientId\" ${oauth_type === 'tooljet_app' ? 'environment variable' : 'config'} is missing","messagePattern":"Google OAuth \"clientId\" (.+?) is missing","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"marketplace/plugins/googlecalendar/lib/index.ts","lineNumber":25,"sourceCode":"} from '@tooljet-marketplace/common';\nimport { SourceOptions, ConvertedFormat, QueryResult } from './types';\nimport got, { Headers, OptionsOfTextResponseBody } from 'got';\n\nexport default class GoogleCalendar implements QueryService {\n  authUrl(source_options: SourceOptions): string {\n    const host = process.env.TOOLJET_HOST;\n    const subpath = process.env.SUB_PATH;\n    const fullUrl = `${host}${subpath ? subpath : '/'}`;\n    const oauth_type = source_options.oauth_type.value;\n    let clientId: string;\n    if (oauth_type === 'tooljet_app') {\n      clientId = process.env.GOOGLE_CLIENT_ID;\n    } else {\n      clientId = source_options?.client_id?.value;\n    }\n    const scope = 'https://www.googleapis.com/auth/calendar';\n    if (!clientId) {\n      throw new Error(\n        `Google OAuth \"clientId\" ${oauth_type === 'tooljet_app' ? 'environment variable' : 'config'} is missing`\n      );\n    }\n\n    const encodedScope = this.encodeOAuthScope(scope);\n    const baseUrl =\n      'https://accounts.google.com/o/oauth2/v2/auth' +\n      `?response_type=code&client_id=${clientId}` +\n      `&redirect_uri=${fullUrl}oauth2/authorize`;\n    const authUrl = `${baseUrl}&scope=${encodedScope}&access_type=offline&prompt=consent`;\n    return authUrl;\n  }\n\n  private encodeOAuthScope(scope: string): string {\n    return encodeURIComponent(scope);\n  }\n\n  async run(","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/ToolJet/ToolJet/blob/20602a8e101f2e59686c9afde0d1402aac2c8871/marketplace/plugins/googlecalendar/lib/index.ts#L7-L43","documentation":"The Google Calendar plugin's authUrl() reads the OAuth clientId from either the GOOGLE_CLIENT_ID environment variable (when oauth_type === 'tooljet_app') or from source_options.client_id.value. If neither resolves to a truthy string, this plain Error is thrown before any redirect URL is built. It is a configuration-time failure surfaced at the first attempt to start OAuth.","triggerScenarios":"User selects 'tooljet_app' OAuth mode but the operator has not set GOOGLE_CLIENT_ID in the server env; OR user selects the custom ('config') mode but leaves the client_id field blank in the datasource config. Also triggered if oauth_type.value itself is undefined (the .value access would throw first, but a falsy clientId after that hits this branch).","commonSituations":"Fresh deploy of ToolJet without the GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET env vars set; misconfigured secret manager that injects an empty string; switching from tooljet_app to custom OAuth and forgetting to fill the new client_id field; copying source_options between environments and dropping the nested {value:\"...\"} structure.","solutions":["If using tooljet_app mode: set GOOGLE_CLIENT_ID (and GOOGLE_CLIENT_SECRET) in the server environment and restart the process.","If using custom mode: open the datasource configuration and supply client_id.value (and client_secret.value) from the Google Cloud Console credential.","Verify the value is a non-empty string — an empty-string env var still fails the !clientId check.","Confirm source_options.oauth_type.value is one of 'tooljet_app' or a custom mode so the correct branch resolves clientId."],"exampleFix":"// before (env empty)\n// .env: GOOGLE_CLIENT_ID=\n\n// after\n// .env:\nGOOGLE_CLIENT_ID=123456-abc.apps.googleusercontent.com\nGOOGLE_CLIENT_SECRET=yourSecret\n\n// OR, in datasource config (custom mode):\nsource_options = {\n  oauth_type: { value: 'custom' },\n  client_id: { value: '123456-abc.apps.googleusercontent.com' },\n  client_secret: { value: 'yourSecret' }\n};","handlingStrategy":"validation","validationCode":"function resolveGoogleCalendarClientId(source_options, env = process.env) {\n  const oauth_type = source_options?.oauth_type?.value;\n  const clientId = oauth_type === 'tooljet_app'\n    ? env.GOOGLE_CLIENT_ID\n    : source_options?.client_id?.value;\n  if (!clientId) {\n    throw new Error(\n      `Google OAuth clientId missing (mode=${oauth_type}). Set GOOGLE_CLIENT_ID env or client_id config.`\n    );\n  }\n  return clientId;\n}\nresolveGoogleCalendarClientId(source_options);","typeGuard":"function hasGoogleCalendarClientId(source_options, env = process.env): boolean {\n  const oauth_type = source_options?.oauth_type?.value;\n  return oauth_type === 'tooljet_app'\n    ? !!env.GOOGLE_CLIENT_ID\n    : !!source_options?.client_id?.value;\n}","tryCatchPattern":"try {\n  const url = plugin.authUrl(source_options);\n} catch (e) {\n  if (/clientId.*missing/.test(e.message)) {\n    // prompt operator to set GOOGLE_CLIENT_ID or fill client_id config\n  }\n  throw e;\n}","preventionTips":["On startup, log a warning if GOOGLE_CLIENT_ID is unset when tooljet_app mode is enabled.","Document the env var in the datasource setup screen beside the oauth_type selector.","Run a config self-check at deploy time that lists plugins with missing required env vars."],"tags":["oauth","google-calendar","configuration","env-vars","tooljet"],"backgroundTag":null,"analyzedSha":"20602a8e101f2e59686c9afde0d1402aac2c8871","analyzedAt":"2026-08-13T05:58:54.221Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}