{"record":{"id":"74364eadbedc7724","repo":"mastra-ai/mastra","slug":"language-must-be-a-two-letter-code-e-g-en-es","errorCode":null,"errorMessage":"language must be a two-letter code (e.g. \"en\", \"es\")","messagePattern":"language must be a two-letter code \\(e\\.g\\. \"en\", \"es\"\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integrations/brightdata/src/client.ts","lineNumber":150,"sourceCode":"  return body;\n}\n\nexport function getBrightDataClient(config?: BrightDataClientOptions): BrightDataClient {\n  const apiKey = config?.apiKey ?? process.env.BRIGHTDATA_API_TOKEN;\n  if (!apiKey) {\n    throw new Error('Bright Data API token is required. Pass { apiKey } or set BRIGHTDATA_API_TOKEN env var.');\n  }\n\n  const timeout = config?.timeout;\n  const serpZone = config?.serpZone ?? process.env.BRIGHTDATA_SERP_ZONE ?? DEFAULT_SERP_ZONE;\n  const webUnlockerZone =\n    config?.webUnlockerZone ?? process.env.BRIGHTDATA_WEB_UNLOCKER_ZONE ?? DEFAULT_WEB_UNLOCKER_ZONE;\n\n  return {\n    search: {\n      google: async (query: string, options: SearchOptions = {}) => {\n        if (options.language && !/^[a-z]{2}$/i.test(options.language)) {\n          throw new Error('language must be a two-letter code (e.g. \"en\", \"es\")');\n        }\n\n        const normalizedOptions = options.language ? { ...options, language: options.language.toLowerCase() } : options;\n\n        const url = buildGoogleSearchUrl(query, normalizedOptions);\n        return requestBrightData(\n          apiKey,\n          toRequestBody(url, normalizedOptions.zone ?? serpZone, {\n            ...normalizedOptions,\n            format: normalizedOptions.format ?? 'json',\n            method: 'GET',\n          }),\n          normalizedOptions.timeout ?? timeout,\n        );\n      },\n    },\n    scrapeUrl: async (url: string, options: RequestOptions = {}) => {\n      const response = await requestBrightData(","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/integrations/brightdata/src/client.ts#L132-L168","documentation":"When client.search.google is called with a language option, getBrightDataClient validates it against /^[a-z]{2}$/i (a two-letter code). Anything else — full names like 'english', locales like 'en-US', or empty/whitespace values — throws this error before any network request is made. Valid codes are normalized to lowercase before building the request.","triggerScenarios":"Calling search.google(query, { language: 'english' }), { language: 'en-US' }, or any string that is not exactly two alphabetic characters.","commonSituations":"Passing a human-readable language name from UI state; passing an RFC 4646 locale tag ('en-US', 'pt-BR'); binding a select input that stores labels instead of ISO 639-1 codes.","solutions":["Pass an ISO 639-1 two-letter code, e.g. { language: 'en' } or { language: 'es' }.","Convert locale tags to their language subtag before calling: 'en-US' -> 'en'.","Validate/normalize user-supplied language input at the boundary before invoking the client."],"exampleFix":"// before\nawait client.search.google(q, { language: 'en-US' });\n// after\nawait client.search.google(q, { language: 'en-US'.split('-')[0] }); // 'en'","handlingStrategy":"validation","validationCode":"function normalizeLanguage(input?: string): string | undefined {\n  if (!input) return undefined;\n  const code = input.split('-')[0].toLowerCase();\n  if (!/^[a-z]{2}$/.test(code)) {\n    throw new Error(`language must be an ISO 639-1 two-letter code, got: ${input}`);\n  }\n  return code;\n}\n// usage: client.search.google(q, { ...options, language: normalizeLanguage(options.language) })","typeGuard":"function isTwoLetterLanguage(v: unknown): v is string {\n  return typeof v === 'string' && /^[a-z]{2}$/.test(v);\n}","tryCatchPattern":null,"preventionTips":["Always pass ISO 639-1 codes ('en', 'es'), never names or locale tags.","Convert 'xx-YY' locale tags to their language subtag before calling.","Validate language inputs at the UI/API boundary before they reach the client.","Prefer omitting the language option when unknown instead of guessing a value."],"tags":["validation","parameters","i18n"],"backgroundTag":"parameter-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}