openclaw/openclaw · warning · Error

telegram runtime unavailable (runtime keys: ${runtimeKeys.jo

Error message

telegram runtime unavailable (runtime keys: ${runtimeKeys.join(",")}; channel keys: ${channelKeys.join(",")})

What it means

Thrown in the device-pair setup command (extensions/device-pair/index.ts:982) when the channel is telegram and a target exists, the plugin loads the telegram outbound adapter via api.runtime.channel.outbound.loadAdapter('telegram'), but the resulting adapter has no sendText method. This path attempts to split the QR-image delivery from the setup code across two messages. The throw is immediately caught by the surrounding try/catch (line 1001) which logs a warning and falls back to a single combined text message — so the user still receives a setup code. The error message includes runtime/channel key listings purely for diagnostics.

Source

Thrown at extensions/device-pair/index.ts:982

        const payload = await issueSetupPayload({
          url: urlResult.url,
          urls: urlResult.urls,
          allowFullAccess: authState.canIssueFullAccessSetup,
        });

        if (channel === "telegram" && target) {
          try {
            const runtimeKeys = Object.keys(api.runtime ?? {});
            const channelKeys = Object.keys(api.runtime?.channel ?? {});
            api.logger.debug?.(
              `device-pair: runtime keys=${runtimeKeys.join(",") || "none"} channel keys=${
                channelKeys.join(",") || "none"
              }`,
            );
            const adapter = await api.runtime.channel.outbound.loadAdapter("telegram");
            const send = adapter?.sendText;
            if (!send) {
              throw new Error(
                `telegram runtime unavailable (runtime keys: ${runtimeKeys.join(",")}; channel keys: ${channelKeys.join(
                  ",",
                )})`,
              );
            }
            await send({
              cfg: api.config,
              to: target,
              text: formatSetupInstructions(payload.expiresAtMs),
              ...(ctx.messageThreadId != null ? { threadId: ctx.messageThreadId } : {}),
              ...(ctx.accountId ? { accountId: ctx.accountId } : {}),
            });
            api.logger.info?.(
              `device-pair: telegram split send ok target=${target} account=${ctx.accountId ?? "none"} thread=${
                ctx.messageThreadId ?? "none"
              }`,
            );
            return { text: encodeSetupCode(payload) };

View on GitHub (pinned to 01804a7531)

Solutions

  1. No user action required in most cases — the command falls back to a single-message setup code automatically.
  2. If split telegram delivery (image + code) is desired, ensure the telegram channel plugin is installed, enabled, and configured with a valid bot token.
  3. Inspect the device-pair debug log line ('device-pair: runtime keys=... channel keys=...') to see which runtime/channel surfaces are missing.
  4. Run 'openclaw doctor' to verify telegram channel health.
Defensive patterns

Strategy: type-guard

Type guard

function hasTelegramSendText(api: unknown): boolean {
  const runtime = (api as { runtime?: { channel?: { outbound?: { loadAdapter?: unknown } } } })?.runtime;
  return !!runtime?.channel?.outbound && typeof runtime.channel.outbound.loadAdapter === "function";
}

Try / catch

// The throw is already caught internally at index.ts:1001 and degrades to a
// single-message reply. Callers need no extra handling — this is informational.

Prevention

When it happens

Trigger: The telegram outbound adapter fails to load, loads as undefined, or loads but exposes no sendText function — while a telegram setup command is being handled with a valid target recipient.

Common situations: Telegram channel plugin not installed or enabled; runtime version missing the channel.outbound.loadAdapter surface; adapter version mismatch where sendText was renamed/removed; telegram bot not configured so the adapter is inert; partial plugin load after a config reload.

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/1eb8359402076a64. Report an issue: GitHub.