Skip to content

fix(telegram): add dnsResultOrder=ipv4first default on Node 22+ to fix fetch failures#5405

Merged
obviyus merged 5 commits intoopenclaw:mainfrom
Glucksberg:fix/telegram-dns-ipv4first
Feb 22, 2026
Merged

fix(telegram): add dnsResultOrder=ipv4first default on Node 22+ to fix fetch failures#5405
obviyus merged 5 commits intoopenclaw:mainfrom
Glucksberg:fix/telegram-dns-ipv4first

Conversation

@Glucksberg
Copy link
Copy Markdown
Contributor

@Glucksberg Glucksberg commented Jan 31, 2026

Summary

Some networks/ISPs have issues with IPv6 causing Telegram API fetch failures, even with autoSelectFamily=false. This adds a complementary fix using dns.setDefaultResultOrder('ipv4first') to prioritize IPv4 addresses in DNS resolution.

Problem

From #5311:

  • message tool with action=send fails with "Network request for 'sendMessage' failed!"
  • Normal conversation replies work fine
  • Manual curl to Telegram API works
  • autoSelectFamily=false is already applied but not sufficient

Solution

Add dnsResultOrder=ipv4first as default on Node 22+ alongside the existing autoSelectFamily=false:

dns.setDefaultResultOrder('ipv4first');

This matches the workaround suggested in the issue comments:

NODE_OPTIONS='--dns-result-order=ipv4first'

Changes

  • Add dnsResultOrder config option (ipv4first | verbatim)
  • Default to ipv4first on Node 22+
  • Add OPENCLAW_TELEGRAM_DNS_RESULT_ORDER env var override
  • Log the applied setting for debugging

Configuration

{
  "channels": {
    "telegram": {
      "network": {
        "dnsResultOrder": "ipv4first"
      }
    }
  }
}

Or via environment variable:

OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first

Fixes #5311

Greptile Overview

Greptile Summary

This PR adds a Telegram-specific network workaround for Node 22+ by introducing a new channels.telegram.network.dnsResultOrder setting (and env override OPENCLAW_TELEGRAM_DNS_RESULT_ORDER) and applying it via dns.setDefaultResultOrder('ipv4first') alongside the existing autoSelectFamily workaround. Config schema/UI hints and Zod validation were updated accordingly.

Main risk area is the global nature of these Node defaults: the implementation caches “applied” settings and currently marks them applied even if the underlying setter throws, which can prevent later successful application in environments where the setter becomes available.

Confidence Score: 4/5

  • Generally safe to merge, with one correctness edge case around caching the applied network defaults.
  • Changes are small and localized, with schema/type updates consistent across config layers. The primary concern is applyTelegramNetworkWorkarounds() updating applied* state before confirming the runtime setter succeeded, which can lock in a no-op if the call throws.
  • src/telegram/fetch.ts

@openclaw-barnacle openclaw-barnacle bot added the channel: telegram Channel integration: telegram label Jan 31, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +33 to +36
// Apply DNS result order workaround for IPv4/IPv6 issues.
// Some APIs (including Telegram) may fail with IPv6 on certain networks.
// See: https://github.com/openclaw/openclaw/issues/5311
const dnsDecision = resolveTelegramDnsResultOrderDecision({ network });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] applyTelegramNetworkWorkarounds() now sets appliedDnsResultOrder/appliedAutoSelectFamily before attempting dns.setDefaultResultOrder()/net.setDefaultAutoSelectFamily(). If those setters throw (e.g. unsupported runtime), the cache still updates and prevents future attempts even if a later call runs in an environment where it would succeed.

A safer pattern is to only update applied* after the setter succeeds, or revert in the catch.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/fetch.ts
Line: 33:36

Comment:
[P1] `applyTelegramNetworkWorkarounds()` now sets `appliedDnsResultOrder`/`appliedAutoSelectFamily` *before* attempting `dns.setDefaultResultOrder()`/`net.setDefaultAutoSelectFamily()`. If those setters throw (e.g. unsupported runtime), the cache still updates and prevents future attempts even if a later call runs in an environment where it would succeed.

A safer pattern is to only update `applied*` after the setter succeeds, or revert in the `catch`.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +16 to +18
export type TelegramDnsResultOrderDecision = {
value: string | null;
source?: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] TelegramDnsResultOrderDecision.value is typed as string | null, but downstream it’s treated as a strict union ("ipv4first" | "verbatim") and then cast in fetch.ts. Tightening this type to "ipv4first" | "verbatim" | null would remove the need for the cast and prevent accidental future values from compiling.

Also, resolveTelegramDnsResultOrderDecision() already normalizes/filters to those two values, so the narrower type matches current behavior.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/network-config.ts
Line: 16:18

Comment:
[P2] `TelegramDnsResultOrderDecision.value` is typed as `string | null`, but downstream it’s treated as a strict union (`"ipv4first" | "verbatim"`) and then cast in `fetch.ts`. Tightening this type to `"ipv4first" | "verbatim" | null` would remove the need for the cast and prevent accidental future values from compiling.

Also, `resolveTelegramDnsResultOrderDecision()` already normalizes/filters to those two values, so the narrower type matches current behavior.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +74 to +77
// Check config
const configValue = (params?.network as { dnsResultOrder?: string } | undefined)?.dnsResultOrder
?.trim()
.toLowerCase();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] configValue is extracted via (params?.network as { dnsResultOrder?: string })?.dnsResultOrder?.trim().toLowerCase(). Since TelegramNetworkConfig.dnsResultOrder is already a union of string literals, this cast/normalization is redundant and makes the code harder to follow.

If you want case-insensitive config parsing, it might be better handled at schema/parse time rather than by casting away the type here.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/network-config.ts
Line: 74:77

Comment:
[P3] `configValue` is extracted via `(params?.network as { dnsResultOrder?: string })?.dnsResultOrder?.trim().toLowerCase()`. Since `TelegramNetworkConfig.dnsResultOrder` is already a union of string literals, this cast/normalization is redundant and makes the code harder to follow.

If you want case-insensitive config parsing, it might be better handled at schema/parse time rather than by casting away the type here.

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling docs Improvements or additions to documentation and removed docs Improvements or additions to documentation labels Feb 1, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 22, 2026

@Glucksberg is attempting to deploy a commit to the 0xBuns Team on Vercel.

A member of the Team first needs to authorize it.

Glucksberg and others added 5 commits February 22, 2026 20:07
…x fetch failures

Some networks/ISPs have issues with IPv6 causing Telegram API fetch
failures, even with autoSelectFamily=false. This adds a complementary
fix using dns.setDefaultResultOrder('ipv4first') to prioritize IPv4
addresses in DNS resolution.

Changes:
- Add dnsResultOrder config option (ipv4first | verbatim)
- Default to 'ipv4first' on Node 22+ alongside existing autoSelectFamily=false
- Add OPENCLAW_TELEGRAM_DNS_RESULT_ORDER env var override
- Log the applied setting for debugging

The combination of autoSelectFamily=false and dnsResultOrder=ipv4first
addresses the Happy Eyeballs timeout and IPv6 resolution issues that
cause 'Network request failed' errors on certain network configurations.

Fixes openclaw#5311
)

OpenRouter's 'auto' model is stored in the registry with the full id
'openrouter/auto', but parseModelRef splits 'openrouter/auto' into
provider='openrouter' and modelId='auto'. The registry lookup then
fails because it searches for id='auto' instead of 'openrouter/auto'.

This adds a fallback that tries the full id when the initial lookup
fails for this specific case.
@obviyus
Copy link
Copy Markdown
Contributor

obviyus commented Feb 22, 2026

Merged via squash.

Thanks @Glucksberg!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: telegram Channel integration: telegram size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Telegram message tool fails with 'fetch failed' while normal replies work (Node 22)

2 participants