Skip to content

Discord adapter renders bare URLs as [url](url) masked links, which display as literal text #565

@furgin

Description

@furgin

Bug Description

When the Discord adapter converts a message containing a bare URL or an autolink (https://…) from mdast to Discord markdown, it wraps it as a masked link https://example.com. Discord only renders masked-link syntax inside embeds — in a normal message, text is shown as literal text. So a plain URL that should be a clean, clickable link instead appears to the user as the raw string https://example.com.

The root cause is in DiscordFormatConverter's link handling (packages/adapter-discord/src/markdown.ts, the isLinkNode branch of nodeToDiscordMarkdown): it unconditionally emits ${linkText} with no special case for when the link's label equals its URL (the bare-URL / autolink case).

Steps to Reproduce

  1. Create a Chat instance with the Discord adapter.
  2. From a handler, post a message containing a bare URL as markdown, e.g. await thread.post({ markdown: "https://example.com" }) (or have any flow that produces an mdast link node whose text equals its URL — bare URLs and both do).
  3. Observe the message in Discord.

Expected Behavior

The bare URL is sent through as-is (https://example.com) and renders as a clickable link in Discord.

Actual Behavior

The adapter sends https://example.com, which Discord displays as literal text (masked links only render inside embeds), so the link is neither clean nor clickable.

Code Sample

import { DiscordFormatConverter } from "@chat-adapter/discord";

const converter = new DiscordFormatConverter();

// Bare URL
converter.fromAst(converter.toAst("https://example.com"));
// → "[https://example.com](https://example.com)"   ❌ expected: "https://example.com"

// Autolink
converter.fromAst(converter.toAst("<https://example.com>"));
// → "[https://example.com](https://example.com)"   ❌ expected: "https://example.com"

// Labeled links are fine (text !== url):
converter.fromAst(converter.toAst("[click here](https://example.com)"));
// → "[click here](https://example.com)"             ✅

Chat SDK Version

4.29.0

Node.js Version

22.22.2

Platform Adapter

Discord

Operating System

Linux

Additional Context

Existing unit tests in markdown.test.ts only cover labeled links ([link text](url) where text ≠ url), so the bare-URL/autolink case slips through with no coverage. A targeted fix is to short-circuit the isLinkNode branch when linkText === node.url and return the bare URL. I have a fix + failing-then-passing tests ready and am happy to open a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    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