jackwener/OpenCLI · error · CommandExecutionError

Invalid message ID: "${messageId}". A Discord message ID is

Error message

Invalid message ID: "${messageId}". A Discord message ID is a numeric snowflake (e.g. 1234567890123456789).

What it means

Before touching the DOM, the delete command validates that message_id is a numeric snowflake with /^\d+$/ and throws CommandExecutionError if not. Discord message IDs are 64-bit snowflakes; the library rejects anything else up front to avoid building a doomed delete script.

Source

Thrown at clis/discord-app/delete.js:96

    domain: 'localhost',
    strategy: Strategy.UI,
    browser: true,
    args: [
        {
            name: 'message_id',
            type: 'string',
            required: true,
            positional: true,
            help: 'The ID of the message to delete (visible via Developer Mode or the read command)',
        },
    ],
    columns: ['status', 'message'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for discord-app delete');
        const messageId = kwargs.message_id;
        if (!/^\d+$/.test(messageId)) {
            throw new CommandExecutionError(
                `Invalid message ID: "${messageId}". A Discord message ID is a numeric snowflake (e.g. 1234567890123456789).`
            );
        }
        // Wait a moment for the chat to be fully loaded
        await page.wait(0.5);
        const result = await page.evaluate(buildDeleteScript(messageId));
        if (result.ok) {
            await page.wait(1);
        }
        return [{
            status: result.ok ? 'success' : 'failed',
            message: result.message,
        }];
    },
});

export const __test__ = {
    buildDeleteScript,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass only the numeric message ID: enable Discord Developer Mode, right-click the message, 'Copy Message ID', and use that digits-only value.
  2. Extract the last numeric segment of a message link: const id = url.split('/').pop();
  3. Trim whitespace and avoid quotes/commas around the value.
  4. If using a variable, coerce/validate with /^\d+$/.test(id) before calling the command.

Example fix

// before
run(`discord-app delete --message_id="${url}"`);
// after
const messageId = url.split('/').pop();
if (!/^\d+$/.test(messageId)) throw new Error('Not a snowflake ID');
run(`discord-app delete --message_id=${messageId}`);
Defensive patterns

Strategy: validation

Validate before calling

const messageId = String(kwargs.message_id || '').trim();
if (!/^\d+$/.test(messageId)) throw new Error(`Bad snowflake: ${messageId}`);

Type guard

function isSnowflakeId(v) { return typeof v === 'string' && /^\d+$/.test(v.trim()); }

Try / catch

try {
  await run(`discord-app delete --message_id=${messageId}`);
} catch (e) {
  if (/Invalid message ID/.test(e.message)) {
    console.error('Use Copy Message ID (Developer Mode) — digits only');
  }
}

Prevention

When it happens

Trigger: Passing a non-numeric message_id (e.g. 'abc', '123-456'), a value with whitespace or quotes, a float-formatted number, an empty string, or copying the wrong ID (channel/user snowflakes still pass the regex but wrong ID types fail later; letters/symbols fail here).

Common situations: Copying the message link but pasting the channel ID portion instead of the message ID; pasting a URL like 'https://discord.com/channels/.../123' without extracting the last segment; typing the ID by hand with a typo.

Related errors


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