jackwener/OpenCLI · error · CommandExecutionError

${context} could not verify returned message target. Expecte

Error message

${context} could not verify returned message target. Expected channel/thread id ${expectedChannelId}, but the message row did not include channel_id.

What it means

During target verification each message row must carry a channel_id so the library can prove the messages came from the requested channel. When a well-formed row has an empty/missing channel_id, the check is inconclusive and CommandExecutionError is thrown with the expected id in the detail line.

Source

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

        requireArrayEvaluateResult(await page.evaluate(buildListThreadsScript(limit)), 'Discord thread list'),
        ['Thread', 'guild_id', 'channel_id', 'thread_id', 'url'],
        'Discord thread list',
    );
}

export function assertDiscordMessageRowsBelongToTarget(rows, target, context = 'Discord read') {
    if (!target) return rows;
    const expectedChannelId = String(target.thread_id || target.channel_id || '');
    if (!expectedChannelId) {
        throw new CommandExecutionError(`${context} target is missing a stable channel/thread id.`);
    }
    for (const row of rows) {
        if (!row || typeof row !== 'object' || Array.isArray(row)) {
            throw new CommandExecutionError(`${context} returned malformed message rows.`);
        }
        const actualChannelId = row.channel_id == null || row.channel_id === '' ? '' : String(row.channel_id);
        if (!actualChannelId) {
            throw new CommandExecutionError(
                `${context} could not verify returned message target.`,
                `Expected channel/thread id ${expectedChannelId}, but the message row did not include channel_id.`,
            );
        }
        if (actualChannelId && actualChannelId !== expectedChannelId) {
            throw new CommandExecutionError(
                `${context} returned messages from the wrong Discord target.`,
                `Expected channel/thread id ${expectedChannelId}, saw ${actualChannelId}.`,
            );
        }
    }
    return rows;
}

export async function resolveDiscordThreadTarget(page, kwargs = {}) {
    const urlArg = stringArg(kwargs.url);
    if (urlArg) {
        const parsed = parseDiscordChannelUrl(urlArg);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update the message extractor so each row includes channel_id.
  2. Re-run the read after letting the channel fully load (wait for Discord content) so rows are stamped correctly.
  3. If you control the rows, hydrate them: rows.map(r => ({ ...r, channel_id: r.channel_id ?? expectedId })).
  4. Compare with "opencli discord-app messages -f json" output to see whether channel_id is being produced at all.

Example fix

// before
rows.push({ id: 'm1', content: 'hi' }); // no channel_id
// after
rows.push({ id: 'm1', content: 'hi', channel_id: target.channel_id });
Defensive patterns

Strategy: validation

Validate before calling

if (rows.some(r => r && typeof r === 'object' && !Array.isArray(r) && (r.channel_id == null || r.channel_id === ''))) throw new Error('Some rows lack channel_id; scraper output stale');

Type guard

function hasChannelId(r) { return r !== null && typeof r === 'object' && !Array.isArray(r) && typeof String(r.channel_id ?? '') === 'string' && String(r.channel_id ?? '').length > 0; }

Try / catch

try { assertDiscordMessageRowsBelongToTarget(rows, target, ctx); } catch (e) { if (String(e.message).includes('could not verify returned message target')) { // re-harvest after content ready: await waitForDiscordContent(page,'messages');
} else throw e; }

Prevention

When it happens

Trigger: A row object in rows lacks channel_id (null, undefined, or empty string) while the expected target has a valid thread_id/channel_id — usually because the scraper omitted the field when attributing the row.

Common situations: Discord UI variant (forum/thread view) where the extractor fails to stamp channel_id on rows; custom/old scraper output predating the channel_id field; rows reconstructed from partial page data.

Related errors


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