Skip to content

message tool misclassifies empty channelId/to fields as legacy params #38830

@lin-1259

Description

@lin-1259

Summary

The message tool may reject valid target-based sends with:

Use target instead of to/channelId

when the caller correctly uses target and does not intentionally use legacy to or channelId.

Root cause

In src/infra/outbound/channel-target.ts, the legacy-param detection checks only whether the fields exist as strings:

const hasLegacyTo = typeof params.args.to === "string";
const hasLegacyChannelId = typeof params.args.channelId === "string";

This incorrectly treats empty strings like to: "" or channelId: "" as legacy-param usage.

Some tool wrappers / runtimes populate optional fields with empty-string defaults, which causes valid calls using target to fail.

Expected behavior

Only non-empty legacy fields should trigger the error.

Actual behavior

A request like this can fail:

{
  "action": "send",
  "channel": "telegram",
  "target": "1214056829",
  "filePath": "/workspace/example.png",
  "channelId": ""
}

with:

Use `target` instead of `to`/`channelId`.

Proposed fix

Change the checks to require non-empty strings:

const hasLegacyTo =
  typeof params.args.to === "string" && params.args.to.trim().length > 0;

const hasLegacyChannelId =
  typeof params.args.channelId === "string" &&
  params.args.channelId.trim().length > 0;

Why this matters

This bug creates inconsistent behavior across model/tool wrappers:

  • wrappers that emit only minimal fields succeed
  • wrappers that include empty-string defaults fail

So the same logical request may succeed in one agent path and fail in another.

Local validation

After applying the fix and rebuilding, the same environment successfully sent:

  • image-only messages
  • image + text messages
  • captioned images
  • txt file attachments

Environment

  • OpenClaw version: 2026.3.2
  • Channel tested: Telegram
  • Affected workflow: message(action=send) with target

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions