{"record":{"id":"25247f5ae323bb0c","repo":"jackwener/OpenCLI","slug":"pass-thread-thread-id-or-url-thread-url","errorCode":null,"errorMessage":"Pass --thread <thread_id> or --url <thread_url>.","messagePattern":"Pass --thread <thread_id> or --url <thread_url>\\.","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/discord-app/utils.js","lineNumber":631,"sourceCode":"            );\n        }\n    }\n    return rows;\n}\n\nexport async function resolveDiscordThreadTarget(page, kwargs = {}) {\n    const urlArg = stringArg(kwargs.url);\n    if (urlArg) {\n        const parsed = parseDiscordChannelUrl(urlArg);\n        if (!parsed || !parsed.thread_id) {\n            throw new ArgumentError('--url must be a Discord thread/post URL like https://discord.com/channels/<guild_id>/<channel_id>/<thread_id>.');\n        }\n        return parsed;\n    }\n\n    const threadArg = stringArg(kwargs.thread);\n    if (!threadArg) {\n        throw new ArgumentError('Pass --thread <thread_id> or --url <thread_url>.');\n    }\n\n    const parsedThreadUrl = parseDiscordChannelUrl(threadArg);\n    if (parsedThreadUrl?.thread_id) return parsedThreadUrl;\n\n    const channelTarget = hasDiscordChannelTarget(kwargs)\n        ? await resolveDiscordChannelTarget(page, kwargs, { required: true })\n        : null;\n    if (channelTarget) {\n        return {\n            guild_id: channelTarget.guild_id,\n            channel_id: channelTarget.channel_id,\n            thread_id: threadArg,\n            url: buildDiscordChannelUrl({\n                guildId: channelTarget.guild_id,\n                channelId: channelTarget.channel_id,\n                threadId: threadArg,\n            }),","sourceCodeStart":613,"sourceCodeEnd":649,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/discord-app/utils.js#L613-L649","documentation":"resolveDiscordThreadTarget resolves a Discord thread target from CLI args. This ArgumentError is thrown when neither --thread nor --url was provided, so there is no way to identify the thread. It is a usage error, not a runtime failure.","triggerScenarios":"Calling a discord-app command that needs a thread (e.g. reading/posting in a thread) without passing --thread <thread_id> or --url <thread_url>; passing --thread as an empty string or whitespace-only value so stringArg(kwargs.thread) yields ''.","commonSituations":"Developers copy examples that only set --guild/--channel and forget the thread id; scripting the CLI where the thread id variable is unset; confusing channel id with thread id and omitting --thread entirely.","solutions":["Pass --thread <thread_id> with the thread's id","Pass --url <thread_url> with the Discord message/thread URL instead","Ensure the --thread value is non-empty (check the shell variable is set)","If you only have a channel, open the parent forum/channel context first so the current channel can imply the thread"],"exampleFix":"// before\ncli thread-read --guild 123 --channel 456\n// after\ncli thread-read --thread 987654321098765432","handlingStrategy":"validation","validationCode":"if (!process.env.THREAD_ID && !args.url) throw new Error('Provide --thread <id> or --url <thread_url>');","typeGuard":"function hasThreadTarget(a) { return typeof a === 'object' && a !== null && (typeof a.thread === 'string' && a.thread.trim() !== '' || typeof a.url === 'string' && a.url.trim() !== ''); }","tryCatchPattern":"try { await target(args); } catch (e) { if (e instanceof ArgumentError && /--thread/.test(e.message)) { console.error('Usage: pass --thread <id> or --url <url>'); process.exitCode = 2; } else throw e; }","preventionTips":["Always pass --thread or --url for thread commands","Validate CLI args in wrapper scripts before invoking","Use shell : \"${VAR:?}\" guards for variables feeding flags"],"tags":["cli","argument-validation","discord"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}