jackwener/OpenCLI · error · ArgumentError

Pass --channel with --guild, or use --url.

Error message

Pass --channel with --guild, or use --url.

What it means

resolveDiscordChannelTarget throws this ArgumentError when --guild is provided but --channel is not. The guild alone narrows the server but does not identify a channel, so the resolver refuses the partial selection and points at --url as the alternative.

Source

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

    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 }),
        };
    }

    const channels = await listDiscordChannels(page);
    const match = channels.find((row) => rowMatchesGuild(row, guildId) && rowMatchesChannel(row, channelArg));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Add --channel <channel_id_or_name> alongside --guild.
  2. Or drop --guild/--channel and use a single --url https://discord.com/channels/<guild_id>/<channel_id>.
  3. Quote the channel value in the shell (e.g. --channel "general") so it is not swallowed as a flag.

Example fix

// before
await resolveDiscordChannelTarget(page, { guild: '123456789' }); // missing channel
// after
await resolveDiscordChannelTarget(page, { guild: '123456789', channel: '987654321' });
Defensive patterns

Strategy: validation

Validate before calling

if (opts.guild && !opts.channel && !opts.url) throw new Error('--guild requires --channel (or use --url)');

Type guard

function hasGuildWithoutChannel(k = {}) { return Boolean(k.guild) && !k.channel && !k.url; }

Try / catch

try { await runCommand(args); } catch (e) { if (String(e.message).startsWith('Pass --channel with --guild')) { args.push('--channel', resolveChannelId(args.guild)); return runCommand(args); } throw e; }

Prevention

When it happens

Trigger: Calling resolveDiscordChannelTarget with kwargs.guild set (e.g. --guild 'My Server' or a guild id) and kwargs.channel empty/undefined.

Common situations: Copy-pasting only part of a flag pair in shell scripts; a quoting bug that drops the --channel value; thinking --guild alone means 'first channel of the server'.

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/51c0d24f2cb86b57. Report an issue: GitHub.