jackwener/OpenCLI · error · ArgumentError
--attach expects attachmentId UUIDs; "${aid}" is not a UUID
Error message
--attach expects attachmentId UUIDs; "${aid}" is not a UUID What it means
message-send.js parses `--attach` as a comma-separated list of attachmentId UUIDs and validates each against UUID_RE. Any entry that isn't a valid UUID throws this ArgumentError naming the bad entry.
Source
Thrown at clis/slock/message-send.js:35
siteSession: 'persistent',
args: [
{ name: 'target', positional: true, required: true, help: '"#channel", "#channel:msgIdOrShort", "dm:@name", "dm:<uuid>", or channel UUID' },
{ name: 'content', positional: true, required: true, help: 'Message body (sent verbatim, no marker)' },
{ name: 'dry-run', type: 'bool', default: false, help: 'Print the planned payload without sending' },
{ name: 'as-task', type: 'bool', default: false, help: 'Create the message as a task (asTask)' },
{ name: 'attach', help: 'Comma-separated attachmentId UUIDs (upload separately first)' },
{ name: 'server', help: 'Override active server (slug or id)' },
],
columns: ['target', 'channelId', 'content', 'result', 'messageId'],
func: async (page, kwargs) => {
const target = String(kwargs.target ?? '').trim();
if (!target) throw new ArgumentError('target required');
const content = String(kwargs.content ?? '');
const asTask = !!kwargs['as-task'];
const attachmentIds = String(kwargs.attach ?? '')
.split(',').map((s) => s.trim()).filter(Boolean);
for (const aid of attachmentIds) {
if (!UUID_RE.test(aid)) throw new ArgumentError(`--attach expects attachmentId UUIDs; "${aid}" is not a UUID`);
}
let cls;
try { cls = classifyTarget(target); }
catch (e) { throw new ArgumentError(e.message); }
const extra = { asTask, attachmentIds };
if (kwargs['dry-run']) {
return [{
target, channelId: '(not resolved in dry-run)', content,
result: asTask ? 'dry-run (asTask)' : 'dry-run', messageId: null,
}];
}
await page.goto(SLOCK_HOME_URL);
const snippet = buildSendSnippet(target, content, cls, kwargs.server, extra);
const result = await page.evaluate(`(async () => { ${snippet} })()`);
const rows = dispatchEvaluateResult(result);View on GitHub (pinned to 49907e53dc)
Solutions
- Upload the file first (upload command) and use the returned attachmentId UUID.
- Fix typos/truncation in the UUID (must match the standard UUID format).
- Comma-separate multiple ids without extra tokens: `--attach <uuid1>,<uuid2>`.
Example fix
// before --attach ./report.pdf // after --attach 9b2f0a1c-3d4e-4f5a-8b9c-0d1e2f3a4b5c
Defensive patterns
Strategy: validation
Validate before calling
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
for (const aid of String(kwargs.attach ?? '').split(',').map(s => s.trim()).filter(Boolean)) {
if (!UUID_RE.test(aid)) throw new Error(`--attach needs attachmentId UUIDs; "${aid}" is not a UUID`);
} Type guard
const isUuid = (v) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(String(v)); Try / catch
try { await sendMessage(page, kwargs); } catch (e) { if (String(e.message).includes('--attach expects attachmentId UUIDs')) { console.error('Upload files first and pass returned attachmentId UUIDs'); } else throw e; } Prevention
- Always upload files first; use the returned attachmentId, not the file path
- Validate UUID format in scripts before invoking message-send
- Split comma lists and trim tokens before passing --attach
When it happens
Trigger: Passing `--attach` values that are file paths, filenames, short ids, upload-returned names instead of UUIDs, or a list with stray whitespace-adjacent garbage tokens.
Common situations: Passing local file paths to --attach instead of uploading first and using returned attachmentIds; copying a truncated UUID; comma+space splitting leaving empty or malformed tokens.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b98116ee3d0622b7.
Report an issue: GitHub.