{"record":{"id":"0ef064cecd789166","repo":"jackwener/OpenCLI","slug":"attachmentid-id-is-not-a-uuid-0ef064","errorCode":null,"errorMessage":"attachmentId \"${id}\" is not a UUID","messagePattern":"attachmentId \"(.+?)\" is not a UUID","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/slock/attachment-url.js","lineNumber":33,"sourceCode":"import { UUID_RE } from './resolve.js';\n\ncli({\n  site: SLOCK_SITE,\n  name: 'attachment-url',\n  access: 'read',\n  description: 'Get a short-lived signed CDN URL for an attachment (does not download bytes).',\n  domain: SLOCK_DOMAIN,\n  strategy: Strategy.COOKIE,\n  browser: true,\n  siteSession: 'persistent',\n  args: [\n    { name: 'attachmentId', positional: true, required: true, help: 'Attachment UUID' },\n    { name: 'server', help: 'Override active server slug' },\n  ],\n  columns: ['attachmentId', 'url', 'expiresAt'],\n  func: async (page, kwargs) => {\n    const id = String(kwargs.attachmentId ?? '').trim();\n    if (!UUID_RE.test(id)) throw new ArgumentError(`attachmentId \"${id}\" is not a UUID`);\n    await page.goto(SLOCK_HOME_URL);\n    const snippet = buildFetchSnippet({\n      method: 'GET',\n      path: `/attachments/${encodeURIComponent(id)}/url`,\n      serverScoped: true,\n      serverIdOverride: kwargs.server,\n    });\n    const result = await page.evaluate(`(async () => { ${snippet} })()`);\n    const rows = dispatchEvaluateResult(result);\n    const data = Array.isArray(rows) ? rows[0] : rows;\n    if (!data?.url) {\n      throw new CommandExecutionError(`no signed url returned for attachment ${id}`);\n    }\n    return [{\n      attachmentId: id,\n      url: data?.url ?? null,\n      expiresAt: data?.expiresAt ?? null,\n    }];","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/attachment-url.js#L15-L51","documentation":"This ArgumentError is thrown by the attachment-url command when the attachmentId argument does not match the UUID regular expression. Attachment IDs are UUIDs issued by the server; anything else would produce a malformed API path, so the CLI validates the shape before navigating and running the fetch snippet.","triggerScenarios":"Passing a non-UUID string as the positional attachmentId — e.g. a numeric database id, a URL, a filename, an empty string after trimming, or an ID from a different system.","commonSituations":"Copying the wrong column from a previous listing (e.g. server id instead of attachment id), pasting a URL fragment instead of the bare UUID, or using an id from another chat platform.","solutions":["Run the attachment listing command to get the correct UUID-form attachmentId and pass that.","Strip any URL/path prefix so only the bare UUID remains (e.g. extract the last path segment).","Validate the format first: /^[0-9a-f]{8}-[0-9a-f]{4}-.../i (standard 8-4-4-4-12 hex pattern) before invoking.","Confirm the attachment exists on the target server; ids from other servers won't resolve."],"exampleFix":"// before\nawait attachmentUrl(page, process.argv[2]); // \"https://slock.example/attachments/abc\"\n// after\nconst id = process.argv[2].split('/').pop();\nif (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)) throw new Error('not a UUID');\nawait attachmentUrl(page, id);","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nif (!UUID_RE.test(attachmentId)) throw new Error(`attachmentId must be a UUID, got: ${attachmentId}`);","typeGuard":"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);","tryCatchPattern":"try {\n  await attachmentUrl(page, id);\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.includes('is not a UUID')) {\n    console.error(`Bad id \"${id}\" — re-list attachments to get the UUID`);\n  } else throw e;\n}","preventionTips":["Always take attachmentId from the CLI/API listing output, never free text.","Run ids through isUuid() at script boundaries.","Strip URL prefixes before passing an id that came from a link."],"tags":["validation","uuid","argument-error","input-validation"],"backgroundTag":"invalid-uuid-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}