jackwener/OpenCLI · error · ArgumentError
status "${status}" not in {${TASK_STATUSES.join('|')}}
Error message
status "${status}" not in {${TASK_STATUSES.join('|')}} What it means
In task-list, the optional --status flag is validated against the TASK_STATUSES allowlist after the channel check. Any provided value not exactly matching a canonical status (after trim) throws an ArgumentError enumerating the valid values, avoiding a guaranteed-400 request.
Source
Thrown at clis/slock/task-list.js:40
name: 'task-list',
access: 'read',
description: 'List tasks (chat tasks = messages with task fields) attached to a channel. Optional --status filter.',
domain: SLOCK_DOMAIN,
strategy: Strategy.COOKIE,
browser: true,
siteSession: 'persistent',
args: [
{ name: 'channel', positional: true, required: true, help: 'channelId UUID or #name' },
{ name: 'status', help: `Filter by status: ${TASK_STATUSES.join('|')}` },
{ name: 'server', help: 'Override active server' },
],
columns: ['id', 'taskNumber', 'title', 'taskStatus', 'assigneeId'],
func: async (page, kwargs) => {
const channel = String(kwargs.channel ?? '').trim();
if (!channel) throw new ArgumentError('channel required');
const status = kwargs.status ? String(kwargs.status).trim() : '';
if (status && !TASK_STATUSES.includes(status)) {
throw new ArgumentError(`status "${status}" not in {${TASK_STATUSES.join('|')}}`);
}
await page.goto(SLOCK_HOME_URL);
const snippet = `
${authHeadersFragment({ serverScoped: true, serverIdOverride: kwargs.server })}
${channelResolveFragment(channel)}
const status = ${JSON.stringify(status)};
const qs = status ? ('?status=' + encodeURIComponent(status)) : '';
const tres = await fetch('${SLOCK_API_BASE}/tasks/channel/' + encodeURIComponent(channelId) + qs, { credentials:'include', headers });
if (!tres.ok) return { kind: tres.status===401?'auth':'http', status: tres.status, where: '/tasks/channel/:id' };
const data = await tres.json();
// Server contract: { tasks: [...] }. Reject anything else as drift.
if (!data || !Array.isArray(data.tasks)) {
return { kind: 'http', status: 200, where: '/tasks/channel/:id (expected {tasks:[]}, got drift)' };
}
return { kind: 'ok', rows: data.tasks };
`;
const result = await page.evaluate(`(async () => { ${snippet} })()`);
const rows = dispatchEvaluateResult(result);View on GitHub (pinned to 49907e53dc)
Solutions
- Check `slock task-list --help` and use exactly one of the listed statuses
- Normalize the value (lowercase/underscore) to match the canonical tokens
- Omit --status to list all and filter client-side
- Validate user-supplied status in your wrapper script against the same TASK_STATUSES list
Example fix
// before
await cli('slock', 'task-list', '--channel', 'general', '--status', 'Closed');
// after
await cli('slock', 'task-list', '--channel', 'general', '--status', 'closed'); // exact member Defensive patterns
Strategy: validation
Validate before calling
import { TASK_STATUSES } from 'clis/slock/task-statuses.js';
if (status && !TASK_STATUSES.includes(status.trim())) {
throw new Error(`status must be one of: ${TASK_STATUSES.join('|')}`);
} Type guard
const isValidStatus = (s) => s == null || TASK_STATUSES.includes(String(s).trim());
Prevention
- Use --help to confirm the canonical status strings
- Normalize casing before passing --status
- Validate user input against TASK_STATUSES in wrapper scripts
When it happens
Trigger: Running `slock task-list --channel <ch> --status <value>` where value is not a member of TASK_STATUSES — wrong casing, alias tokens ('doing', 'wip'), typos, or values copied from other tools.
Common situations: Guessing the status vocabulary; case drift ('Open' vs 'open'); stale scripts written against an older status set that was later renamed; interpolating user input without validation.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- status "${status}" not in {${TASK_STATUSES.join('|')}}
- 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
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/f40485449a9cbc54.
Report an issue: GitHub.