jackwener/OpenCLI · error · ArgumentError

Pass --url or --guild/--channel to choose a Discord channel.

Error message

Pass --url or --guild/--channel to choose a Discord channel.

What it means

resolveDiscordChannelTarget throws this ArgumentError when no channel selector is supplied at all (no --url, no --guild, no --channel) while options.required is set. The caller explicitly demanded a channel target, so returning null is not allowed.

Source

Thrown at clis/discord-app/utils.js:473

    if (!guild) return true;
    return String(row.guild_id || '') === guild || normalizeDiscordName(row.Server) === normalizeDiscordName(guild);
}

export async function resolveDiscordChannelTarget(page, kwargs = {}, options = {}) {
    const urlArg = stringArg(kwargs.url);
    if (urlArg) {
        const parsed = parseDiscordChannelUrl(urlArg);
        if (!parsed || parsed.thread_id) {
            throw new ArgumentError('--url must be a Discord channel URL like https://discord.com/channels/<guild_id>/<channel_id>.');
        }
        return parsed;
    }

    const guildArg = stringArg(kwargs.guild);
    const channelArg = stringArg(kwargs.channel);
    if (!guildArg && !channelArg) {
        if (options.required) {
            throw new ArgumentError('Pass --url or --guild/--channel to choose a Discord channel.');
        }
        return null;
    }
    if (!channelArg) {
        throw new ArgumentError('Pass --channel with --guild, or use --url.');
    }

    let guildId = guildArg;
    if (guildArg && !isDiscordSnowflake(guildArg) && guildArg !== '@me') {
        const server = (await listDiscordServers(page)).find((row) => rowMatchesGuild(row, guildArg));
        if (server?.guild_id) guildId = String(server.guild_id);
    }

    if (guildId && isDiscordSnowflake(guildId) && isDiscordSnowflake(channelArg)) {
        return {
            guild_id: guildId,
            channel_id: channelArg,
            url: buildDiscordChannelUrl({ guildId, channelId: channelArg }),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass --url https://discord.com/channels/<guild_id>/<channel_id>.
  2. Or pass both --guild and --channel.
  3. Or pass --channel together with --guild as numeric snowflake ids (run "opencli discord-app channels -f json" to find them).

Example fix

// before
opencli discord-app messages
// after
opencli discord-app messages --url https://discord.com/channels/123456789/987654321
Defensive patterns

Strategy: validation

Validate before calling

if (!opts.url && !opts.guild && !opts.channel) throw new Error('Provide --url or --guild/--channel before invoking');

Type guard

function hasChannelSelector(k = {}) { return Boolean(k.url || k.guild || k.channel); }

Try / catch

try { await runCommand(args); } catch (e) { if (String(e.message).startsWith('Pass --url or --guild/--channel')) { console.error('Usage: --url <channel-url> | --guild <g> --channel <c>'); } else throw e; }

Prevention

When it happens

Trigger: Invoking a command that calls resolveDiscordChannelTarget with { required: true } and providing none of --url, --guild, or --channel in kwargs.

Common situations: Forgetting required flags in scripts/CI; omitting arguments after refactoring a command; assuming a previously selected channel persists between invocations when it does not.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/09a775a083741363. Report an issue: GitHub.