jackwener/OpenCLI · error · ArgumentError
attachmentId "${id}" is not a UUID
Error message
attachmentId "${id}" is not a UUID What it means
An ArgumentError thrown during argument validation of the slock attachment-download CLI command: the provided attachmentId does not match UUID_RE, so it cannot be a valid Slock attachment identifier. The download flow (signed URL resolution, CDN fetch) is aborted before any network calls.
Source
Thrown at clis/slock/attachment-download.js:42
cli({
site: SLOCK_SITE,
name: 'attachment-download',
access: 'read',
description: 'Download an attachment to a local file. Resolves a signed CDN URL in the page, then fetches bytes node-side (no CORS).',
domain: SLOCK_DOMAIN,
strategy: Strategy.COOKIE,
browser: true,
siteSession: 'persistent',
args: [
{ name: 'attachmentId', positional: true, required: true, help: 'Attachment UUID' },
{ name: 'out', help: 'Local path to write to. Defaults to ./<attachmentId>.bin' },
{ name: 'server', help: 'Override active server slug' },
],
columns: ['attachmentId', 'out', 'sizeBytes'],
func: async (page, kwargs) => {
const id = String(kwargs.attachmentId ?? '').trim();
if (!UUID_RE.test(id)) throw new ArgumentError(`attachmentId "${id}" is not a UUID`);
const out = path.resolve(String(kwargs.out ?? `./${id}.bin`));
// Step 1 — in-page, resolve the signed URL with the user's Slock session.
await page.goto(SLOCK_HOME_URL);
const snippet = buildFetchSnippet({
method: 'GET',
path: `/attachments/${encodeURIComponent(id)}/url`,
serverScoped: true,
serverIdOverride: kwargs.server,
});
const result = await page.evaluate(`(async () => { ${snippet} })()`);
const rows = dispatchEvaluateResult(result);
const data = Array.isArray(rows) ? rows[0] : rows;
const url = data?.url;
if (!url) throw new CommandExecutionError(`no signed url returned for attachment ${id}`);
// Step 2 — Node side, fetch the bytes from the signed CDN URL. No auth
// header (URL is pre-signed); no Origin (Node fetch has none) so CORSView on GitHub (pinned to 49907e53dc)
Solutions
- Re-copy the full UUID of the attachment (8-4-4-4-12 hex format) and pass it again
- Check you are using the attachment's UUID, not its numeric ID or filename
- Trim surrounding quotes/whitespace from the argument in your shell invocation
- Run the list command (same CLI) to get valid attachmentIds with their columns
Example fix
// before node cli attachment-download --attachmentId 12345 // after node cli attachment-download --attachmentId 550e8400-e29b-41d4-a716-446655440000
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;
if (!UUID_RE.test(String(id ?? '').trim())) {
throw new Error('attachmentId must be a canonical UUID');
} Type guard
const isUuid = (v) => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v.trim()); Prevention
- Copy full UUIDs from the list command output, not partial URL fragments
- Do not substitute numeric database IDs for attachment UUIDs
- Quote UUID arguments in shells that interpret dashes or special characters
- Validate IDs in scripts before invoking the CLI to fail fast
When it happens
Trigger: Passing kwargs.attachmentId that is empty, whitespace-only, a numeric database ID, a truncated/copied-partial UUID, or a value with surrounding characters instead of a canonical UUID string.
Common situations: Copying only part of the attachment ID from a UI URL; passing an integer row ID from a database export; forgetting the argument entirely (empty string after trim); pasting an ID wrapped in quotes or with trailing whitespace/newline.
Related errors
- ${label} is required
- ${label} must be a positive integer
- ${label} must be <= ${maxValue}
- dblp ${label} must be a positive integer
- dblp ${label} must be <= ${maxValue}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d9b7167a7ec33b0f.
Report an issue: GitHub.