{"record":{"id":"f323e5d7a02e4740","repo":"jackwener/OpenCLI","slug":"channel-required-f323e5","errorCode":null,"errorMessage":"channel required","messagePattern":"channel required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/slock/channel-members.js","lineNumber":24,"sourceCode":"import { SLOCK_SITE, SLOCK_DOMAIN, SLOCK_HOME_URL } from './shared.js';\n\ncli({\n  site: SLOCK_SITE,\n  name: 'channel-members',\n  access: 'read',\n  description: 'List members of a channel',\n  domain: SLOCK_DOMAIN,\n  strategy: Strategy.COOKIE,\n  browser: true,\n  siteSession: 'persistent',\n  args: [\n    { name: 'channel', positional: true, required: true, help: 'channelId UUID or #name' },\n    { name: 'server', help: 'Override active server (slug or id)' },\n  ],\n  columns: ['userId', 'name', 'kind', 'role'],\n  func: async (page, kwargs) => {\n    const channel = String(kwargs.channel ?? '').trim();\n    if (!channel) throw new ArgumentError('channel required');\n    await page.goto(SLOCK_HOME_URL);\n    const snippet = buildChannelScopedSnippet({\n      channelInput: channel,\n      method: 'GET',\n      pathSuffix: '/members',\n      serverIdOverride: kwargs.server,\n    });\n    const result = await page.evaluate(`(async () => { ${snippet} })()`);\n    const data = dispatchEvaluateResult(result);\n    // F2-a — qatester live dump: response is `{ agents: [...], humans: [...] }`,\n    // NOT a flat array and NOT under `.members`. Combine both lists and tag each\n    // row with `kind` so the caller can tell agents from humans. Fall back to\n    // the legacy shapes (`.members` / `.data` / bare array) for forward-compat.\n    let agents = [], humans = [];\n    if (Array.isArray(data)) {\n      humans = data;\n    } else if (data) {\n      agents = Array.isArray(data.agents) ? data.agents : [];","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/channel-members.js#L6-L42","documentation":"The slock channel-members command requires a channel argument (a channelId UUID or #name). The CLI throws this ArgumentError when the positional --channel value is missing or empty after trimming. It is a fail-fast input guard before any browser automation or API call is made.","triggerScenarios":"Running `opencli slock channel-members` without the positional channel argument, or passing only whitespace/empty string (e.g. from a shell variable that expanded to empty: `opencli slock channel-members \"$CH\"` where CH is unset).","commonSituations":"Shell scripts with unset/empty channel variables; copy-pasting the command from docs without filling in the channel; forgetting that the channel is positional and trying `--channel` with the wrong subcommand placement.","solutions":["Pass the channel as a positional argument: `opencli slock channel-members '#general'` or `opencli slock channel-members <uuid>`","If using a shell variable, verify it is non-empty before invoking: `[ -n \"$CH\" ] || { echo 'CH not set'; exit 1; }`","Run `opencli slock channel-list` first to obtain a valid channelId or #name"],"exampleFix":"// before\nopencli slock channel-members\n// after\nopencli slock channel-members '#general'","handlingStrategy":"validation","validationCode":"const channel = (process.argv[3] ?? '').trim();\nif (!channel) { console.error('usage: opencli slock channel-members <channelId|#name>'); process.exit(2); }","typeGuard":"const isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"try { await runChannelMembers(channel); } catch (e) { if (e instanceof ArgumentError) { console.error('Missing --channel:', e.message); process.exit(2); } throw e; }","preventionTips":["Always pass the channel positionally, quoted if it starts with #","Check shell variables with [ -n \"$CH\" ] before invoking","Fetch ids with `slock channel-list` and store them in scripts"],"tags":["cli","argument-error","input-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}