{"record":{"id":"938de318ff383698","repo":"jackwener/OpenCLI","slug":"messageid-required-938de3","errorCode":null,"errorMessage":"messageId required","messagePattern":"messageId required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/slock/task-convert.js","lineNumber":40,"sourceCode":"import { UUID_RE, classifyThreadTarget } from './resolve.js';\n\ncli({\n  site: SLOCK_SITE,\n  name: 'task-convert',\n  access: 'write',\n  description: 'Convert a message into a chat task (POST /tasks/convert-message). Accepts a message UUID or \"#channel:shortId\".',\n  domain: SLOCK_DOMAIN,\n  strategy: Strategy.COOKIE,\n  browser: true,\n  siteSession: 'persistent',\n  args: [\n    { name: 'messageId', positional: true, required: true, help: 'Full message UUID, or \"#channel:shortId\" (short id expanded via /messages/context)' },\n    { name: 'server', help: 'Override active server' },\n  ],\n  columns: ['id', 'taskNumber', 'title', 'taskStatus', 'channelId'],\n  func: async (page, kwargs) => {\n    const raw = String(kwargs.messageId ?? '').trim();\n    if (!raw) throw new ArgumentError('messageId required');\n\n    // Decide shape: bare UUID, or \"#channel:shortId\".\n    let resolveFragment;\n    if (UUID_RE.test(raw)) {\n      resolveFragment = `const fullMsgId = ${JSON.stringify(raw)};`;\n    } else {\n      const tt = classifyThreadTarget(raw);\n      if (!tt) {\n        throw new ArgumentError(`messageId \"${raw}\" is not a UUID or a \"#channel:shortId\" form`);\n      }\n      const isUuid = UUID_RE.test(tt.parentTarget);\n      const parent = JSON.stringify(tt.parentTarget.replace(/^#/, '').toLowerCase());\n      const pmsg = JSON.stringify(tt.parentMsgId);\n      // Phase 7.1 invariant baked in: we read cxd.targetMessageId, NOT\n      // m.message.id. The latter is the closest-message-in-context object,\n      // which can be a neighbor when the short id is just a prefix.\n      resolveFragment = `\n        let parentChannelId;","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/task-convert.js#L22-L58","documentation":"task-convert requires a positional messageId; the func trims the argument and throws ArgumentError when it is empty. Accepted forms are a full message UUID or a '#channel:shortId' reference expanded via /messages/context.","triggerScenarios":"Running task-convert with no positional argument, or with a value that is whitespace only after trimming.","commonSituations":"Piping an empty variable into the command; forgetting the argument when converting a message to a task; a shell expansion that produced an empty string.","solutions":["Provide the message UUID or '#channel:shortId' as the positional argument.","Verify the variable feeding the argument is non-empty before invoking.","Check command usage/help to confirm the positional argument name and accepted forms."],"exampleFix":"// before\nslock task-convert \"$MSG_ID\"   # MSG_ID is empty\n// after\n: \"${MSG_ID:?MSG_ID must be set}\" && slock task-convert \"$MSG_ID\"","handlingStrategy":"validation","validationCode":"const raw = String(messageId ?? '').trim();\nif (!raw) throw new Error('messageId is required (UUID or #channel:shortId)');","typeGuard":"const hasMessageId = (v) => typeof v === 'string' && v.trim().length > 0;","tryCatchPattern":"try {\n  await cli('task-convert', msgId);\n} catch (e) {\n  if (e instanceof ArgumentError && e.message === 'messageId required') {\n    console.error('Usage: task-convert <messageUUID | #channel:shortId>');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Guard message-id variables with ${VAR:?msg} in scripts.","Quote positional arguments so whitespace-only values fail loudly upstream.","Confirm the source of the id (message list/context output) before converting."],"tags":["cli","missing-argument","input-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}