{"record":{"id":"cbf6dc0e6ecf0266","repo":"jackwener/OpenCLI","slug":"query-required","errorCode":null,"errorMessage":"query required","messagePattern":"query required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/slock/message-search.js","lineNumber":27,"sourceCode":"cli({\n  site: SLOCK_SITE,\n  name: 'message-search',\n  access: 'read',\n  description: 'Search messages',\n  domain: SLOCK_DOMAIN,\n  strategy: Strategy.COOKIE,\n  browser: true,\n  siteSession: 'persistent',\n  args: [\n    { name: 'query', positional: true, required: true, help: 'Search query' },\n    { name: 'channel', help: 'Restrict to a channel (UUID or #name)' },\n    { name: 'limit', type: 'int', default: 50, help: 'Max results' },\n    { name: 'server', help: 'Override active server' },\n  ],\n  columns: ['id', 'channelId', 'createdAt', 'senderName', 'content'],\n  func: async (page, kwargs) => {\n    const q = String(kwargs.query ?? '').trim();\n    if (!q) throw new ArgumentError('query required');\n    const channel = String(kwargs.channel ?? '').trim();\n    const isUuid = channel ? UUID_RE.test(channel) : false;\n    const target = channel ? JSON.stringify(channel.replace(/^#/, '').toLowerCase()) : '\"\"';\n    // R1 — raw override; authHeadersFragment owns the UUID-vs-slug resolution.\n    const override = kwargs.server ?? null;\n    const limit = parsePositiveInteger(kwargs.limit, '--limit', { defaultValue: 50 });\n    await page.goto(SLOCK_HOME_URL);\n    const snippet = `\n      ${authHeadersFragment({ serverScoped: true, serverIdOverride: override })}\n      let channelId = '';\n      if (${JSON.stringify(channel)}) {\n        if (${isUuid}) {\n          channelId = ${JSON.stringify(channel)};\n        } else {\n          const cres = await fetch('${SLOCK_API_BASE}/channels/', { credentials:'include', headers });\n          if (!cres.ok) return { kind: cres.status===401?'auth':'http', status: cres.status, where:'/channels/' };\n          const arr = await cres.json();\n          const hit = (Array.isArray(arr)?arr:(arr.channels||arr.data||[])).find((c) => (c.name||c.slug||'').toLowerCase() === ${target});","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/slock/message-search.js#L9-L45","documentation":"message-search.js requires a `query` argument. If the kwarg is missing or trims to an empty string it throws ArgumentError('query required').","triggerScenarios":"Invoking the message-search command without `--query`, or with an empty/whitespace-only value.","commonSituations":"Building the query dynamically from another command whose output was empty; forgetting the flag; quoting issues causing the shell to swallow the argument.","solutions":["Pass a search term: e.g. `--query \"deploy failure\"`.","Verify the variable feeding the query is non-empty before invoking.","Check shell quoting so the argument isn't dropped or split."],"exampleFix":"// before\nawait run('message-search', { channel: '#general' });\n// after\nawait run('message-search', { channel: '#general', query: 'deploy failure' });","handlingStrategy":"validation","validationCode":"const q = String(kwargs.query ?? '').trim();\nif (!q) throw new Error('message-search: --query is required');","typeGuard":"const query = typeof kwargs.query === 'string' && kwargs.query.trim() ? kwargs.query.trim() : null;\nif (!query) throw new Error('query required');","tryCatchPattern":"try { await searchMessages(page, kwargs); } catch (e) { if (e instanceof ArgumentError && e.message === 'query required') { console.error('Usage: message-search --query \"term\"'); } else throw e; }","preventionTips":["Always pass a non-empty --query","Guard dynamic query sources (upstream command output) for emptiness","Quote queries in shells so they are not dropped"],"tags":["missing-argument","cli","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}