{"record":{"id":"cfc87087e3df4b4a","repo":"mastra-ai/mastra","slug":"telegramprovider-needs-a-baseurl-to-register-a-web","errorCode":null,"errorMessage":"TelegramProvider needs a baseUrl to register a webhook. Set `baseUrl`, configure the Mastra server, or use `mode: \"polling\"`.","messagePattern":"TelegramProvider needs a baseUrl to register a webhook\\. Set `baseUrl`, configure the Mastra server, or use `mode: \"polling\"`\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"channels/telegram/src/telegram-provider.ts","lineNumber":233,"sourceCode":"    if (!options.botToken) {\n      const installationId = existing?.id ?? randomUUID();\n      await store.save({\n        id: installationId,\n        agentId,\n        webhookId: existing?.webhookId ?? randomUUID(),\n        status: 'pending',\n        installedAt: existing?.installedAt ?? new Date(),\n      });\n      return { type: 'deep_link', url: BOTFATHER_DEEP_LINK, installationId };\n    }\n\n    const me = await getMe(options.botToken, this.#apiBaseUrl());\n    const installationId = existing?.id ?? randomUUID();\n    const webhookId = existing?.webhookId ?? randomUUID();\n    const baseUrl = this.#getBaseUrl();\n    const mode = this.#resolveMode(baseUrl);\n    if (mode === 'webhook' && !baseUrl) {\n      throw new Error(\n        'TelegramProvider needs a baseUrl to register a webhook. Set `baseUrl`, configure the Mastra server, or use `mode: \"polling\"`.',\n      );\n    }\n    const webhookUrl = mode === 'webhook' ? `${baseUrl}/${PLATFORM}/events/${webhookId}` : undefined;\n    const commands = normalizeCommands(options.commands ?? this.#config.commands ?? DEFAULT_COMMANDS);\n    const installation: TelegramInstallation = {\n      id: installationId,\n      agentId,\n      webhookId,\n      status: 'active',\n      botToken: options.botToken,\n      secretToken: generateSecretToken(),\n      username: options.name ?? me.username ?? me.first_name,\n      webhookUrl,\n      commands: commands.length ? commands : undefined,\n      installedAt: existing?.installedAt ?? new Date(),\n    };\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/channels/telegram/src/telegram-provider.ts#L215-L251","documentation":"In webhook mode, Telegram must be able to POST updates back to your server, which requires a publicly reachable baseUrl. resolveMode() selects 'webhook' when a baseUrl is present (or the configured mode demands it), and if mode is webhook but baseUrl is empty/undefined, connect() cannot build the webhook URL `${baseUrl}/telegram/events/${webhookId}` and throws.","triggerScenarios":"Instantiating TelegramProvider without a baseUrl option and without a Mastra server configured, while mode resolves to 'webhook' (the default when a URL is expected); calling connect() in an environment with no server URL set.","commonSituations":"Local development without a public URL (no tunneling); deployed app missing the BASE_URL/public URL env var; serverless/edge setup where the library cannot infer the Mastra server address.","solutions":["Pass a public baseUrl to the TelegramProvider options (must be reachable by Telegram servers)","Configure the Mastra server so the library can infer its public URL","Explicitly switch to long polling for local dev: mode: 'polling' in the provider config or connect options","For local testing, expose the server via a tunnel (e.g. ngrok) and use the tunnel URL as baseUrl"],"exampleFix":"// before\nconst provider = new TelegramProvider({ botToken });\n// after\nconst provider = new TelegramProvider({ botToken, mode: 'polling' });\n// or, for webhooks:\nconst provider = new TelegramProvider({ botToken, baseUrl: 'https://my-app.example.com' });","handlingStrategy":"validation","validationCode":"if (mode === 'webhook' && !baseUrl) {\n  throw new Error('Provide a public baseUrl (or use mode: \"polling\") before connecting');\n}","typeGuard":"function hasPublicBaseUrl(o: { baseUrl?: string; mode?: string }): boolean {\n  return o.mode === 'polling' || typeof o.baseUrl === 'string' && o.baseUrl.startsWith('https://');\n}","tryCatchPattern":"try {\n  await provider.connect(agentId, { botToken });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('needs a baseUrl')) {\n    await provider.connect(agentId, { botToken, mode: 'polling' }); // dev fallback\n    return;\n  }\n  throw err;\n}","preventionTips":["Set the public BASE_URL env var in every deployed environment","Use polling mode locally and webhook mode in production via env-driven config","Verify the baseUrl is reachable by Telegram (public https, not localhost)","Point a tunnel (ngrok etc.) at the dev server if webhooks are needed locally"],"tags":["telegram","configuration","webhook","missing-env-var"],"backgroundTag":"missing-base-url","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}