jackwener/OpenCLI · error · ArgumentError
channel required (UUID or #name); server rejects uploads wit
Error message
channel required (UUID or #name); server rejects uploads without channelId
What it means
This ArgumentError is thrown by `attachment-upload` in clis/slock/attachment-upload.js:52 when the `channel` argument is missing or blank. The Slock server requires every attachment upload to be scoped to a channel — the command appends `channelId` as a multipart part and the server returns 400 'channelId is required' without it — so the CLI validates the argument locally before doing any upload work.
Source
Thrown at clis/slock/attachment-upload.js:52
site: SLOCK_SITE,
name: 'attachment-upload',
access: 'write',
description: 'Upload a local file to Slock attachments. Prints the attachmentId for use with `message-send --attach`.',
domain: SLOCK_DOMAIN,
strategy: Strategy.COOKIE,
browser: true,
siteSession: 'persistent',
args: [
{ name: 'file', positional: true, required: true, help: 'Local file path to upload (single file; max 50 MB)' },
{ name: 'channel', positional: true, required: true, help: 'channelId UUID or #name — server requires the attachment be scoped to a channel' },
{ name: 'server', help: 'Override active server slug' },
],
columns: ['attachmentId', 'filename', 'mimeType', 'sizeBytes'],
func: async (page, kwargs) => {
const filePath = String(kwargs.file ?? '').trim();
if (!filePath) throw new ArgumentError('file path required');
const channel = String(kwargs.channel ?? '').trim();
if (!channel) throw new ArgumentError('channel required (UUID or #name); server rejects uploads without channelId');
const abs = path.resolve(filePath);
let stat;
try { stat = fs.statSync(abs); }
catch (e) { throw new ArgumentError(`file not readable: ${abs} (${e.message})`); }
if (!stat.isFile()) throw new ArgumentError(`not a regular file: ${abs}`);
if (stat.size === 0) throw new ArgumentError(`file is empty: ${abs}`);
if (stat.size > MAX_BYTES) {
throw new ArgumentError(`file is ${stat.size} bytes, exceeds server limit ${MAX_BYTES} (50 MiB). Split or compress before upload.`);
}
const buf = fs.readFileSync(abs);
const filename = path.basename(abs);
const b64 = buf.toString('base64');
await page.goto(SLOCK_HOME_URL);
const snippet = `
${authHeadersFragment({ serverScoped: true, serverIdOverride: kwargs.server })}View on GitHub (pinned to 49907e53dc)
Solutions
- Provide the channel as the second positional argument: `attachment-upload ./file.png #general` or with the channel UUID.
- If you only have a channel name, use the `#name` form — the command resolves it in-page to a UUID via channelResolveFragment.
- Retrieve the channelId from a prior channel-list command and pass it explicitly in scripts.
Example fix
// before: missing channel argument attachment-upload ./incident-log.zip // after: scope the upload to a channel (name or UUID) attachment-upload ./incident-log.zip "#incident-reports"
Defensive patterns
Strategy: validation
Validate before calling
const channel = String(process.argv[3] ?? '').trim();
if (!channel) {
throw new Error('channel required: pass a channelId UUID or #name as the second argument');
} Try / catch
try {
await upload({ file, channel });
} catch (e) {
if (e instanceof ArgumentError && e.message.startsWith('channel required')) {
console.error('Usage: attachment-upload <file> <channelId|#name>');
process.exitCode = 2;
} else throw e;
} Prevention
- Always pass a channel (UUID or `#name`) with every attachment upload — the server hard-requires channelId.
- Store the target channel per environment in your script config so it is never omitted.
- Resolve channel names to UUIDs once with a channel-list command and reuse the UUID in automation.
When it happens
Trigger: Running `attachment-upload ./file.png` without the second positional argument, or passing an empty/whitespace-only channel value. Scripts that omit the channel positional while only passing `--server` also hit this.
Common situations: Users assume the channel is inferred from context or configured elsewhere; automation templates omit the channel when adapting message-send invocations to attachment-upload; channel argument dropped when reordering positional arguments in a script.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- channel required
- symbol is required
- <username> is required
- <game-url> is required
- Either --product-id or --url is required
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6dacc6db1585aab9.
Report an issue: GitHub.