{"record":{"id":"28f7f196acbbd4c6","repo":"jackwener/OpenCLI","slug":"could-not-resolve-discord-channel-channelarg","errorCode":null,"errorMessage":"Could not resolve Discord channel \"${channelArg}\". Use \"opencli discord-app channels -f json\" and retry with --url or numeric --guild/--channel ids.","messagePattern":"Could not resolve Discord channel \"(.+?)\"\\. Use \"opencli discord-app channels -f json\" and retry with --url or numeric --guild/--channel ids\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/discord-app/utils.js","lineNumber":516,"sourceCode":"        return {\n            guild_id: String(match.guild_id),\n            channel_id: String(match.channel_id),\n            url: String(match.url || buildDiscordChannelUrl({ guildId: match.guild_id, channelId: match.channel_id })),\n        };\n    }\n\n    if (!guildId && isDiscordSnowflake(channelArg)) {\n        const route = await getCurrentDiscordRoute(page);\n        if (route?.guild_id) {\n            return {\n                guild_id: route.guild_id,\n                channel_id: channelArg,\n                url: buildDiscordChannelUrl({ guildId: route.guild_id, channelId: channelArg }),\n            };\n        }\n    }\n\n    throw new ArgumentError(\n        `Could not resolve Discord channel \"${channelArg}\".`,\n        'Use \"opencli discord-app channels -f json\" and retry with --url or numeric --guild/--channel ids.',\n    );\n}\n\nexport async function waitForDiscordRoute(page, target, options = {}) {\n    const timeoutMs = options.timeoutMs ?? 8000;\n    const intervalSeconds = options.intervalSeconds ?? 0.5;\n    const started = Date.now();\n    let lastState = null;\n\n    while (Date.now() - started <= timeoutMs) {\n        lastState = requireObjectEvaluateResult(await page.evaluate(buildRouteStateScript()), 'Discord route state');\n        const route = lastState?.route;\n        if (route && String(route.guild_id) === String(target.guild_id) && String(route.channel_id) === String(target.channel_id)) {\n            if (!target.thread_id || String(route.thread_id || '') === String(target.thread_id)) {\n                return lastState;\n            }","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/discord-app/utils.js#L498-L534","documentation":"After arg checks pass, resolveDiscordChannelTarget tries to turn --channel (and a non-snowflake --guild) into numeric ids via listDiscordServers/page lookups and route building. If the channel name/id still cannot be mapped to a concrete channel, it throws this ArgumentError with remediation guidance.","triggerScenarios":"The channelArg matched no visible channel in the Discord app (wrong name, channel not loaded, guild not joined), or the guild name did not row-match any listed server, so the route could not be built with a numeric channel_id.","commonSituations":"Passing a channel display name with wrong casing or an alias; the target channel is in a server the bot account cannot see; Discord UI state (server folder collapsed, channel hidden) prevented the lookup; stale channel after server reorganization.","solutions":["Run \"opencli discord-app channels -f json\" to list resolvable channels, then retry with the numeric --guild/--channel ids or the exact --url.","Verify the account is a member of the guild and the channel exists/is visible in the app.","Use the channel id (snowflake) instead of its display name to skip fuzzy lookup.","Enable developer mode in Discord and copy the channel link directly."],"exampleFix":"// before\nawait resolveDiscordChannelTarget(page, { guild: 'My Server', channel: 'genral' }); // typo, unresolvable\n// after\nawait resolveDiscordChannelTarget(page, { guild: '123456789', channel: '987654321' }); // numeric ids","handlingStrategy":"fallback","validationCode":"const listing = await listChannelsJson(); // \"opencli discord-app channels -f json\"\nconst match = listing.find(c => c.name === channelName || c.channel_id === channelArg);\nif (!match) throw new Error(`Unknown channel: ${channelArg}`);","typeGuard":"function isSnowflake(v) { return typeof v === 'string' && /^\\d{15,21}$/.test(v); }","tryCatchPattern":"try { const target = await resolveDiscordChannelTarget(page, kwargs, { required: true }); } catch (e) { if (String(e.message).startsWith('Could not resolve Discord channel')) { // retry with numeric ids from `channels -f json`\n} else throw e; }","preventionTips":["Prefer numeric snowflake ids over display names.","Run \"opencli discord-app channels -f json\" to confirm the channel is visible to the account.","Check casing/aliases; ensure the account has joined the guild."],"tags":["discord","cli","channel-resolution","lookup-failed"],"backgroundTag":"resource-resolution-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}