jackwener/OpenCLI · error · ArgumentError
${e.message} (rethrown as ArgumentError)
Error message
${e.message} (rethrown as ArgumentError) What it means
task-status validates --taskId with assertMessageIdShape and, on failure, rethrows the underlying message wrapped in an ArgumentError. The '(rethrown as ArgumentError)' suffix marks that the original shape-validation error was converted so callers can catch it uniformly as an argument error rather than an internal validation error.
Source
Thrown at clis/slock/task-status.js:38
cli({
site: SLOCK_SITE,
name: 'task-status',
access: 'write',
description: `Set a task's status (PATCH /tasks/:taskId/status, body {status}). One of ${TASK_STATUSES.join('|')}.`,
domain: SLOCK_DOMAIN,
strategy: Strategy.COOKIE,
browser: true,
siteSession: 'persistent',
args: [
{ name: 'taskId', positional: true, required: true, help: 'Full task UUID (= message id; short ids rejected)' },
{ name: 'status', positional: true, required: true, help: `One of: ${TASK_STATUSES.join('|')}` },
{ name: 'server', help: 'Override active server' },
],
columns: ['taskId', 'taskStatus', 'assigneeId', 'taskNumber'],
func: async (page, kwargs) => {
let id;
try { id = assertMessageIdShape(String(kwargs.taskId ?? '')); }
catch (e) { throw new ArgumentError(e.message); }
const status = String(kwargs.status ?? '').trim();
if (!TASK_STATUSES.includes(status)) {
throw new ArgumentError(`status "${status}" not in {${TASK_STATUSES.join('|')}} — pre-network reject (saves a 400 round-trip).`);
}
await page.goto(SLOCK_HOME_URL);
const snippet = `
${authHeadersFragment({ serverScoped: true, serverIdOverride: kwargs.server })}
const res = await fetch('${SLOCK_API_BASE}/tasks/' + encodeURIComponent(${JSON.stringify(id)}) + '/status', {
method:'PATCH', credentials:'include', headers,
body: JSON.stringify({ status: ${JSON.stringify(status)} }),
});
if (res.status === 400) {
const j = await res.json().catch(() => ({}));
return { kind: 'http', status: 400, where: '/tasks/:taskId/status (bad request: ' + (j.error || j.message || 'invalid status transition') + ')' };
}
if (res.status === 403) return { kind: 'http', status: 403, where: '/tasks/:taskId/status (forbidden — terminal status (done/closed), not the assignee, or channel archived)' };
if (res.status === 404) return { kind: 'http', status: 404, where: '/tasks/:taskId/status (task not found)' };
// F6 — actionable hint for repeat-set 409 ("status already X").View on GitHub (pinned to 49907e53dc)
Solutions
- Copy the full task id exactly as shown by task-list output and re-run
- Do not use the numeric taskNumber — fetch the id via `slock task-get --channel <ch> --number <n>`
- Quote the argument in shell to avoid splitting/whitespace loss: --taskId "$ID"
- Check the id against the expected shape (length/charset) before invoking
Example fix
// before
await cli('slock', 'task-status', '--taskId', '42'); // number, not id
// after
await cli('slock', 'task-status', '--taskId', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'); Defensive patterns
Strategy: validation
Validate before calling
const taskId = String(process.env.TASK_ID ?? '').trim();
if (!/^[0-9a-f-]{16,}$/i.test(taskId)) {
throw new Error(`--taskId must be a full task id, got: "${taskId}"`);
} Type guard
const looksLikeTaskId = (v) => typeof v === 'string' && v.trim().length >= 16 && !/^\d+$/.test(v.trim());
Try / catch
try {
await setTaskStatus(taskId, status);
} catch (e) {
if (e.name === 'ArgumentError' && /rethrown as ArgumentError/.test(e.message)) {
// fetch the correct id via task-get before retrying
}
throw e;
} Prevention
- Pass the full task id from task-list/task-get output, never the numeric taskNumber
- Quote shell arguments to preserve the id exactly
- Trim copied ids and re-check length after paste
When it happens
Trigger: Running `slock task-status --taskId <value>` where value fails assertMessageIdShape — empty string, wrong length, non-id characters, or a taskNumber/integer passed where the message-id shape (uuid-like) is expected.
Common situations: Passing the numeric taskNumber instead of the task id; truncated copy-paste of the id; whitespace or quotes captured in the shell argument; unset variable yielding ''.}
Related errors
- archive snapshots url cannot be empty
- archive snapshots limit must be a positive integer
- archive snapshots limit must be <= 1000
- archive snapshots ${key} must be a digit-only timestamp (YYY
- bilibili unfollow target must be a valid space.bilibili.com/
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/58676f9d5f31f061.
Report an issue: GitHub.