jackwener/OpenCLI · error · ArgumentError

${e.message} (rethrown from assertMessageIdShape; e.g. messa

Error message

${e.message} (rethrown from assertMessageIdShape; e.g. messageId "${v}" is not a full UUID)

What it means

reaction-add validates the --messageId argument with assertMessageIdShape, which requires a full UUID. When that validator throws, the command rethrows the message wrapped as an ArgumentError with a 'rethrown from assertMessageIdShape' prefix, naming the offending value. This is a client-side input-shape check, not a server error.

Source

Thrown at clis/slock/reaction-add.js:27

cli({
  site: SLOCK_SITE,
  name: 'reaction-add',
  access: 'write',
  description: 'Add an emoji reaction to a message (POST /messages/:id/reactions). Idempotent server-side.',
  domain: SLOCK_DOMAIN,
  strategy: Strategy.COOKIE,
  browser: true,
  siteSession: 'persistent',
  args: [
    { name: 'messageId', positional: true, required: true, help: 'Full messageId UUID (short ids rejected)' },
    { name: 'emoji', positional: true, required: true, help: 'A single unicode emoji, e.g. 👍' },
    { name: 'server', help: 'Override active server' },
  ],
  columns: ['messageId', 'emoji', 'result'],
  func: async (page, kwargs) => {
    let id;
    try { id = assertMessageIdShape(String(kwargs.messageId ?? '')); }
    catch (e) { throw new ArgumentError(e.message); }
    const emoji = String(kwargs.emoji ?? '').trim();
    if (!emoji) throw new ArgumentError('emoji required (a single unicode emoji)');
    await page.goto(SLOCK_HOME_URL);
    const snippet = buildFetchSnippet({
      method: 'POST',
      path: `/messages/${id}/reactions`,
      body: { emoji },
      serverScoped: true,
      serverIdOverride: kwargs.server,
    });
    const result = await page.evaluate(`(async () => { ${snippet} })()`);
    dispatchEvaluateResult(result);
    return [{ messageId: id, emoji, result: 'added' }];
  },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Get the full UUID from `bookmark-list` or `message-read` output and pass it as --messageId
  2. Verify the value matches a UUID pattern (8-4-4-4-12 hex) before invoking
  3. Check for shell quoting/truncation of the argument

Example fix

// before
$ slock reaction-add --messageId a1b2c3d4 --emoji 👍
// after
$ slock reaction-add --messageId 3f2c9e1a-7b4d-4c8a-9e2f-1a2b3c4d5e6f --emoji 👍
Defensive patterns

Strategy: validation

Validate before calling

const UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
if (!UUID_RE.test(String(messageId ?? ''))) throw new Error(`--messageId must be a full UUID, got: ${messageId}`);

Type guard

function isMessageId(v) {
  return typeof v === 'string' &&
    /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(v);
}

Try / catch

try {
  await cli('reaction-add', { messageId, emoji });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('not a full UUID')) {
    console.error(`Bad messageId "${messageId}"; fetch the full UUID via message-read or bookmark-list.`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `slock reaction-add` with a --messageId value that is empty, or not a full UUID (e.g. an 8-hex short id like `a1b2c3d4`, a numeric id, or a truncated string). The UUID_RE test `/^[0-9a-fA-F]{8}-...-12}$/` fails.

Common situations: Copy-pasting the short `msg=...` id shown in channel headers instead of the full UUID; trimming a UUID when copying; passing a Slack-style timestamp id (`1234567890.123456`); shell quoting issues truncating the value.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/2e393a4bd137c780. Report an issue: GitHub.