#What issue does these logs show?

1 messages ยท Page 1 of 1 (latest)

worn valley
#

Hey krill!

I saw these logs and was wondering what is this issue? what could have caused it? How do resolve or handle it?

I was also wondering if I can configure openclaw to always send cron job results and status to telegram. Sometimes, my agent doesn't setup the delivery options right causing the results to not get sent. Other times, the cron job would fail (either at the job execution or delivery) . I would like to get an error message on telegram.

lofty mothBOT
fluid geyserBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> โœ… Mark Solution

lofty mothBOT
worn valley
#

2026-04-20T12:00:14.478+00:00 [diagnostic] lane wait exceeded: lane=session:agent:main:direct:ahmed waitedMs=19405 queueAhead=0
2026-04-20T12:00:15.325+00:00 [telegram] sendMessage ok chat=1359334095 message=6838
2026-04-20T12:00:22.980+00:00 [ws] โ‡„ res โœ— agent errorCode=UNAVAILABLE errorMessage=Error: Outbound not configured for channel: telegram runId=announce:v1:agent:main:subagent:1eae9f2c-6f04-4236-90e0-8ad525800c31:9c422106-589a-409e-82e2-7c7884e07b70 error=Error: Outbound not configured for channel: telegram conn=a98cbac0โ€ฆ6d05 id=f145f352โ€ฆbf29
2026-04-20T12:00:22.985+00:00 Subagent completion direct announce failed for run 9c422106-589a-409e-82e2-7c7884e07b70: Error: Outbound not configured for channel: telegram
2026-04-20T12:00:24.014+00:00 [ws] โ‡„ res โœ— agent 0ms errorCode=UNAVAILABLE errorMessage=Error: Outbound not configured for channel: telegram cached=true conn=a94ab511โ€ฆec87 id=2db29a53โ€ฆ337e
2026-04-20T12:00:24.018+00:00 Subagent completion direct announce failed for run 9c422106-589a-409e-82e2-7c7884e07b70: Error: Outbound not configured for channel: telegram
2026-04-20T12:00:26.072+00:00 [ws] โ‡„ res โœ— agent 0ms errorCode=UNAVAILABLE errorMessage=Error: Outbound not configured for channel: telegram cached=true conn=c06a0280โ€ฆ1fd7 id=c691eb5fโ€ฆ0cf4
2026-04-20T12:00:26.080+00:00 Subagent completion direct announce failed for run 9c422106-589a-409e-82e2-7c7884e07b70: Error: Outbound not configured for channel: telegram
2026-04-20T12:00:26.086+00:00 [warn] Subagent announce give up (retry-limit) run=9c422106-589a-409e-82e2-7c7884e07b70 child=agent:main:subagent:1eae9f2c-6f04-4236-90e0-8ad525800c31 requester=agent:main:direct:ahmed retries=3 endedAgo=31s

marble auroraBOT
#

I can help, but I canโ€™t see the actual log lines in your message yet.

Please paste:

  1. openclaw --version
  2. the exact log snippet
  3. openclaw cron runs --id <jobId> --limit 50

Without the logs, the most common cron delivery causes are:

  • job is --no-deliver / delivery.mode: "none"
  • missing/invalid channel or to
  • channel auth error (unauthorized / Forbidden)
  • isolated run returned only NO_REPLY (intentionally suppresses send)

Yes, you can make Telegram delivery much more reliable:

#
openclaw cron edit <job-id> \
  --announce --channel telegram --to "<telegram_chat_id>" \
  --no-best-effort-deliver \
  --failure-alert --failure-alert-after 1 \
  --failure-alert-channel telegram --failure-alert-to "<telegram_chat_id>" \
  --failure-alert-cooldown 5m

And set global failure routing in config (applies as default):

cron: {
  failureAlert: {
    enabled: true,
    after: 1,
    cooldownMs: 300000,
#

Nice, these logs are clear now.

What the issue is

  • The real failure is:
    Error: Outbound not configured for channel: telegram
  • It happens during subagent completion announce (not the subagent work itself), then retries, then gives up:
    Subagent announce give up (retry-limit)

What caused it
Most likely one of these:

  1. Telegram outbound is not configured in the active runtime/account used for that announce.
  2. Multi-account mismatch (accountId used by announce/cron doesnโ€™t have a valid Telegram token).
  3. Runtime/plugin state got out of sync after config changes (restart needed).

Also:

  • lane wait exceeded ... waitedMs=19405 is separate, just queue delay (not the root error).
#

To make cron delivery reliable to Telegram and get failure messages there:

openclaw cron edit <job-id> \
  --announce --channel telegram --to "<telegram_chat_id>" --account default \
  --no-best-effort-deliver \
  --failure-alert --failure-alert-after 1 \
  --failure-alert-channel telegram --failure-alert-to "<telegram_chat_id>" \
  --failure-alert-account-id default \
  --failure-alert-cooldown 5m

And set global fallback for all cron failures:

#
cron: {
  failureAlert: {
    enabled: true,
    after: 1,
    cooldownMs: 300000,
    mode: "announce",
    accountId: "default",
  },
  failureDestination: {
    mode: "announce",
    channel: "telegram",
    to: "<telegram_chat_id>",
    accountId: "default",
  },
}
worn valley
#

Is this the correct way to define the default agent configuration?

  "agents": {
    "defaults": {
      "model": {
        "primary": "google/gemini-3-flash-preview"
      },
      "models": {
        "google/gemini-3-flash-preview": {
          "alias": "gemini-flash"
        },
        "moonshot/kimi-k2.5": {
          "alias": "Kimi K2.5"
        },
        "google/gemini-3.1-flash-lite-preview": {
          "alias": "gemini-flash-lite"
        },
        "google/gemini-3.1-pro-preview": {
          "alias": "gemini-pro"
        }
      },
      "workspace": "/home/node/.openclaw/workspace",
      "compaction": {
        "mode": "default",
        "memoryFlush": {
          "enabled": true,
          "softThresholdTokens": 800000
        }
      },
      "thinkingDefault": "low",
      "verboseDefault": "on",
      "heartbeat": {
        "every": "1h",
        "model": "google/gemini-3.1-flash-lite-preview",
        "target": "last"
      },
      "maxConcurrent": 4,
      "subagents": {
        "maxConcurrent": 8
      }
    },
    "list": [
      {
        "id": "main",
        "name": "Main Agent",
        "identity": {
          "name": "Carla",
          "theme": "helpful assistant",
          "emoji": "โญ"
        }
      }
    ]
  },

I used id main but not sure if that would make it the main default agent or just another agent called main. Also how do I define the default fallbacks to use the the gemini lite model then kimi model?

marble auroraBOT
#

Yep, this is mostly correct โœ…

Two key points:

  1. id: "main" is not magical by itself.
    It becomes the default because it is the first (and only) entry in agents.list.
    I still recommend adding default: true explicitly for clarity.

  2. Your fallback chain should be set in agents.defaults.model.fallbacks.

Use:

agents: {
  defaults: {
    models: {
#
      "google/gemini-3-flash-preview": { alias: "gemini-flash" },
      "google/gemini-3.1-flash-lite-preview": { alias: "gemini-flash-lite" },
      "moonshot/kimi-k2.5": { alias: "kimi-k2.5" },
      "google/gemini-3.1-pro-preview": { alias: "gemini-pro" },
    },
    model: {
      primary: "google/gemini-3-flash-preview",
      fallbacks: [
        "google/gemini-3.1-flash-lite-preview",
        "moonshot/kimi-k2.5",
      ],
    },
    // ...rest of your defaults
  },
  list: [
worn valley
#

I am on version 2026.3.24 btw.

Where do I put this in the config?

cron: {
  failureAlert: {
    enabled: true,
    after: 1,
    cooldownMs: 300000,

    mode: "announce",
  },
  failureDestination: {
    mode: "announce",
    channel: "telegram",
    to: "<telegram_chat_id>",
  },
}
marble auroraBOT
#

Perfect, thanks for the version.

Put it in your main config file:

~/.openclaw/openclaw.json

At the top level (same level as agents, channels, etc.):

{
  // ...other config...
  cron: {
    failureAlert: {
      enabled: true,
      after: 1,
      cooldownMs: 300000,
#
      mode: "announce",
      // accountId: "default", // optional, useful for multi-account setups
    },
    failureDestination: {
      mode: "announce",
      channel: "telegram",
      to: "1359334095", // your real chat id
      // accountId: "default", // optional
    },
  },
}

Then restart:

#
openclaw gateway restart

You can also set it without manual editing:

openclaw config set cron.failureAlert.enabled true
openclaw config set cron.failureAlert.after 1
openclaw config set cron.failureAlert.cooldownMs 300000
openclaw config set cron.failureAlert.mode announce
openclaw config set cron.failureDestination '{"mode":"announce","channel":"telegram","to":"1359334095"}'
openclaw gateway restart

Docs: https://docs.openclaw.ai/gateway/configuration-reference#cronfailuredestination and https://docs.openclaw.ai/automation/cron-jobs

worn valley
#

Alright! So I have applied the cron failure configurations. Do I need to update existing cron jobs? do you need to check thier config? or will this apply globally?

marble auroraBOT
#

Great question. Short answer:

  • Failure config (cron.failureAlert + cron.failureDestination) is global and applies to existing jobs too.
  • You only need job edits if you want to override behavior per job.

What can still require per-job updates:

  1. delivery.bestEffort: true on a job, that can suppress failure-notification flow.
    • Fix: openclaw cron edit <job-id> --no-best-effort-deliver
  2. If you also want successful results always to Telegram, each job still needs announce delivery set:
    • openclaw cron edit <job-id> --announce --channel telegram --to "<chat_id>"

Quick audit:

openclaw cron list --json

Check each job for:

  • delivery.mode (announce vs none)
#
  • delivery.channel / delivery.to
  • delivery.bestEffort
  • failureAlert (if explicitly false, it disables alerts for that job)

So, global config is in effect now, but a quick one-time audit of existing jobs is still worth it.

worn valley
#

Great! Now that we have got this covered. What about the outbound config that the logs were referring to regarding the subagents?

marble auroraBOT
#

Yep, that log is about Telegram channel outbound, not cron itself.

For subagent announces, outbound is read from channels.telegram config.
So make sure this is set (same ~/.openclaw/openclaw.json file):

channels: {
  telegram: {
    botToken: "<bot_token>",
    defaultTo: "1359334095",
    actions: {
      sendMessage: true,
    },
    // defaultAccount: "default", // recommended if you use multiple accounts
    // accounts: { default: { botToken: "<bot_token>" } } // multi-account style
  },
#
}

Important for your case:

  • If you use multiple Telegram accounts, set defaultAccount and pass --account default on cron jobs.
  • Keep actions.sendMessage enabled.
  • Restart after config changes: openclaw gateway restart.

Quick outbound test:

openclaw message send --channel telegram --target 1359334095 --message "outbound test"

If this test works but subagent announces still fail, itโ€™s usually an account/route mismatch, then we pin accountId on the job/session path.

worn valley
#

I recently added whatsapp and add a per-peer config.

  "session": {
    "dmScope": "per-peer",
    "identityLinks": {
      "Ahmed": [
        "whatsapp:+20...",
        "telegram:13..."
      ]
    }
  },
  "channels": {
    "whatsapp": {
      "enabled": true,
      "dmPolicy": "allowlist",
      "allowFrom": [
        ""
      ],
      "groupPolicy": "allowlist",
      "debounceMs": 0,
      "mediaMaxMb": 50
    },
    "telegram": {
      "enabled": true,
      "dmPolicy": "allowlist",
      "botToken": "",
      "allowFrom": [
        "tg:"
      ],
      "groupPolicy": "allowlist",
      "streaming": "off",
      "webhookUrl": "",
      "webhookSecret": "",
      "webhookHost": "0.0.0.0",
      "webhookPort": 8788,
      "reactionLevel": "minimal"
    }
  },

Is my config missing anything? are there improvment suggestions?
Note: I have stripped sensitive values

marble auroraBOT
#

Nice setup direction, but yes, a few important fixes.

Biggest issues in your snippet

  1. allowFrom values are effectively empty
  • WhatsApp: [""]
  • Telegram: ["tg:"]
    With dmPolicy: "allowlist", these will block/invalid-authorize DMs.

Use real IDs:

  • WhatsApp: E.164 numbers (e.g. "+20123...")
  • Telegram: numeric user IDs (e.g. "123456789" or "tg:123456789")
  1. If you are not using Telegram webhook mode, remove:
  • webhookUrl, webhookSecret, webhookHost, webhookPort
    (keep config minimal, avoid confusion)

#

About session.dmScope + identityLinks

  • dmScope: "per-peer" is valid.
  • identityLinks is valid for cross-channel unification.
  • Suggest using a stable canonical key (e.g. ahmed instead of Ahmed) for consistency.

Suggested improvements

  • Add channels.telegram.defaultTo (and defaultAccount if multi-account).
  • Consider explicit groupAllowFrom if you keep groupPolicy: "allowlist".
  • Run:
openclaw doctor --fix
openclaw status --deep

to catch normalization/validation issues quickly.

#

If you want, I can rewrite your snippet into a โ€œclean productionโ€ version (polling mode + strict allowlists).

worn valley
#

I told you I stripped sensitive details. There is nothing missing. I just removed my number and ids before sharing the logs.

Now, I haven't applied any of your suggestions yet. What do I need to apply to fix the "Outbound not configured for channel: telegram" issue?

marble auroraBOT
#

Youโ€™re right, stripped values are fine, my bad there.

For this exact error (Outbound not configured for channel: telegram), apply these:

  1. Ensure Telegram outbound is actually enabled
channels: {
  telegram: {
    enabled: true,
    botToken: "<token>",
    actions: { sendMessage: true },
    defaultTo: "<chat_id>"
  }
}

If you use Telegram accounts, also set:

#
channels.telegram.defaultAccount: "default"
  1. Pin account/target on jobs that should notify Telegram
openclaw cron edit <job-id> --announce --channel telegram --to "<chat_id>" --account default
openclaw cron edit <job-id> --failure-alert --failure-alert-channel telegram --failure-alert-to "<chat_id>" --failure-alert-account-id default
  1. Restart gateway
openclaw gateway restart
  1. Verify outbound directly
#
openclaw message send --channel telegram --target <chat_id> --message "telegram outbound test"

One extra stability note: with dmScope: "per-peer" + cross-channel identityLinks, route context can drift between WhatsApp/Telegram.
If you want predictable subagent completion routing, prefer per-channel-peer (or keep per-peer but always pin channel/to/account on cron jobs).

worn valley
#

Why is this warning?

โ—‡  Doctor warnings โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚                                                                                         โ”‚
โ”‚  - channels.telegram: Telegram is in first-time setup mode. DMs use allowlist mode, so  โ”‚
โ”‚    only sender IDs in channels.telegram.allowFrom are accepted. Group messages stay     โ”‚
โ”‚    blocked until you add allowed chats under channels.telegram.groups (and optional     โ”‚
โ”‚    sender IDs under channels.telegram.groupAllowFrom), or set                           โ”‚
โ”‚    channels.telegram.groupPolicy to "open" if you want broad group access.              โ”‚
โ”‚                                                                                         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Why is it considered first time setup mode? what if I want to use the allowlist. I don't want any groups right now.

marble auroraBOT
#

Great catch, and this one is mostly a doctor hint, not a failure.

It says โ€œfirst-time setup modeโ€ because from Telegram doctor logic:

  • you have groupPolicy: "allowlist"
  • but no channels.telegram.groups configured

So doctor assumes: โ€œDMs are configured, groups are not configured yet.โ€

If you donโ€™t want groups at all right now, the clean setting is:

channels: {
  telegram: {
    groupPolicy: "disabled"
  }
}
worn valley
#

what about this security warning? how do I resolve it?

โ”‚ - Heartbeat defaults: heartbeat delivery is configured while โ”‚
โ”‚ agents.defaults.heartbeat.directPolicy is unset. โ”‚
โ”‚ Heartbeat now allows direct/DM targets by default. Set it explicitly to "allow" or โ”‚
โ”‚ "block" to pin upgrade behavior. โ”‚

marble auroraBOT
#

That warning is just saying: you rely on an implicit default.

You configured heartbeat delivery (target/to), but did not set:

agents.defaults.heartbeat.directPolicy

So Doctor asks you to pin behavior explicitly after upgrade.

Use one of these:

agents: {
  defaults: {
    heartbeat: {
      directPolicy: "allow" // allow heartbeat delivery to DMs/direct chats
    }
#
  }
}

or

agents: {
  defaults: {
    heartbeat: {
      directPolicy: "block" // suppress heartbeat delivery to DMs/direct chats
    }
  }
}
#

For your setup (Telegram DM alerts), you probably want "allow".

CLI equivalent:

openclaw config set agents.defaults.heartbeat.directPolicy allow
openclaw gateway restart
worn valley
#

regarding the heartbeat target. it's set to last. what does this mean?