{"record":{"id":"13fc4247480f182a","repo":"jackwener/OpenCLI","slug":"channel-required","errorCode":null,"errorMessage":"channel required","messagePattern":"channel required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/slock/channel-action.js","lineNumber":30,"sourceCode":"// archived channels are excluded from the name lookup (use UUID).\nexport function makeChannelActionCommand({ name, verb, resultLabel, description, archivedHint = false }) {\n  cli({\n    site: SLOCK_SITE,\n    name,\n    access: 'write',\n    description,\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' },\n    ],\n    columns: ['channel', 'id', 'archivedAt', 'result'],\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: 'POST',\n        pathSuffix: `/${verb}`,\n        serverIdOverride: kwargs.server,\n      });\n      const result = await page.evaluate(`(async () => { ${snippet} })()`);\n      let data;\n      try {\n        data = dispatchEvaluateResult(result);\n      } catch (e) {\n        // F7 — channelResolveFragment lists active channels only; archived\n        // channels are absent from the lookup, so `#name` resolve fails for\n        // a channel you're trying to unarchive. UUID still works. Rewrite\n        // the bare \"no channel matches\" message into something actionable.\n        if (archivedHint && e instanceof ArgumentError && /no channel matches/.test(e.message)) {\n          throw new ArgumentError(","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/channel-action.js#L12-L48","documentation":"This ArgumentError is thrown by makeChannelActionCommand's func when the positional `channel` argument is empty after trimming. Channel actions (archive etc.) need a channelId UUID or #name to resolve a channelId server-side; without it the request cannot even be built.","triggerScenarios":"Invoking a channel-action command with the positional argument missing, an empty string, or only whitespace (e.g. a shell variable that expanded to nothing).","commonSituations":"Shell scripts with unset CHANNEL variables (`channel=\"\" archive`), copy-paste dropping the argument, or pipelines where the channel was never resolved from an earlier step.","solutions":["Pass the channel as channelId UUID or #name, e.g. `channel-action archive '#general'`.","Check the shell variable feeding the argument is set and non-empty (`echo \"$CHANNEL\"`).","Resolve the channel first via a channel-list command and use its id or exact #name.","In scripts, guard with `[ -n \"$CHANNEL\" ] || exit 1` before invoking the CLI."],"exampleFix":"// before\nawait channelAction(page, { channel: process.env.CH });\n// after\nif (!process.env.CH?.trim()) throw new Error('CH env var must be a channelId or #name');\nawait channelAction(page, { channel: process.env.CH });","handlingStrategy":"validation","validationCode":"const channel = String(input ?? '').trim();\nif (!channel) throw new Error('channel required: pass a channelId UUID or #name');","typeGuard":"const hasChannelArg = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"try {\n  await channelAction(page, { channel, verb: 'archive' });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message === 'channel required') {\n    console.error('Provide a channel: UUID or #name (check the shell variable was set)');\n  } else throw e;\n}","preventionTips":["Resolve channels via channel-list and pass their id or exact #name.","In shell scripts, guard required variables with [ -n \"$VAR\" ] before invoking.","Quote '#name' arguments so shells don't treat # as a comment."],"tags":["validation","missing-argument","argument-error","channel"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}