jackwener/OpenCLI · error · ArgumentError
messageId required
Error message
messageId required
What it means
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.
Source
Thrown at clis/slock/task-convert.js:40
import { UUID_RE, classifyThreadTarget } from './resolve.js';
cli({
site: SLOCK_SITE,
name: 'task-convert',
access: 'write',
description: 'Convert a message into a chat task (POST /tasks/convert-message). Accepts a message UUID or "#channel:shortId".',
domain: SLOCK_DOMAIN,
strategy: Strategy.COOKIE,
browser: true,
siteSession: 'persistent',
args: [
{ name: 'messageId', positional: true, required: true, help: 'Full message UUID, or "#channel:shortId" (short id expanded via /messages/context)' },
{ name: 'server', help: 'Override active server' },
],
columns: ['id', 'taskNumber', 'title', 'taskStatus', 'channelId'],
func: async (page, kwargs) => {
const raw = String(kwargs.messageId ?? '').trim();
if (!raw) throw new ArgumentError('messageId required');
// Decide shape: bare UUID, or "#channel:shortId".
let resolveFragment;
if (UUID_RE.test(raw)) {
resolveFragment = `const fullMsgId = ${JSON.stringify(raw)};`;
} else {
const tt = classifyThreadTarget(raw);
if (!tt) {
throw new ArgumentError(`messageId "${raw}" is not a UUID or a "#channel:shortId" form`);
}
const isUuid = UUID_RE.test(tt.parentTarget);
const parent = JSON.stringify(tt.parentTarget.replace(/^#/, '').toLowerCase());
const pmsg = JSON.stringify(tt.parentMsgId);
// Phase 7.1 invariant baked in: we read cxd.targetMessageId, NOT
// m.message.id. The latter is the closest-message-in-context object,
// which can be a neighbor when the short id is just a prefix.
resolveFragment = `
let parentChannelId;View on GitHub (pinned to 49907e53dc)
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.
Example fix
// before
slock task-convert "$MSG_ID" # MSG_ID is empty
// after
: "${MSG_ID:?MSG_ID must be set}" && slock task-convert "$MSG_ID" Defensive patterns
Strategy: validation
Validate before calling
const raw = String(messageId ?? '').trim();
if (!raw) throw new Error('messageId is required (UUID or #channel:shortId)'); Type guard
const hasMessageId = (v) => typeof v === 'string' && v.trim().length > 0;
Try / catch
try {
await cli('task-convert', msgId);
} catch (e) {
if (e instanceof ArgumentError && e.message === 'messageId required') {
console.error('Usage: task-convert <messageUUID | #channel:shortId>');
process.exitCode = 2;
} else throw e;
} Prevention
- 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.
When it happens
Trigger: Running task-convert with no positional argument, or with a value that is whitespace only after trimming.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- lobsters domain is required (e.g. "github.com" or "arxiv.org
- input required: slug or UUID
- channel required
- title required (non-empty)
- channel required
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/938de318ff383698.
Report an issue: GitHub.