jackwener/OpenCLI · error · CommandExecutionError

Slock ${commandName} succeeded without returning task id ${e

Error message

Slock ${commandName} succeeded without returning task id ${expectedId}; refusing to report a task row.

What it means

assertTaskIdentity in clis/slock/task-identity.js is a post-condition guard: after a task command 'succeeds', it verifies the returned row actually carries an id. If the row has no id (undefined/null/empty), it refuses to report the row because reporting an unidentifiable task could silently act on the wrong record. This is deliberate defensive behavior against server contract drift.

Source

Thrown at clis/slock/task-identity.js:6

import { CommandExecutionError } from '@jackwener/opencli/errors';

export function assertTaskIdentity(t, expectedId, commandName) {
  const taskId = t?.id;
  if (!taskId) {
    throw new CommandExecutionError(`Slock ${commandName} succeeded without returning task id ${expectedId}; refusing to report a task row.`);
  }
  if (taskId !== expectedId) {
    throw new CommandExecutionError(`Slock ${commandName} returned task id ${taskId}, expected ${expectedId}.`);
  }
  return taskId;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log the raw response body from the slock API to see what shape was actually returned
  2. Check whether the slock API version changed and the task id field was renamed (e.g. to taskId); update row mapping
  3. Confirm authentication is valid — an empty 200 response often means the session/headers were rejected
  4. Update the command's row-mapping code to map the new field name onto `id`, or pin the working API version

Example fix

// before (mapping drops the new field name)
const row = { taskNumber: t.taskNumber, title: t.title };
assertTaskIdentity(row, expectedId, 'task-get');
// after
const row = { id: t.id ?? t.taskId, taskNumber: t.taskNumber, title: t.title };
assertTaskIdentity(row, expectedId, 'task-get');
Defensive patterns

Strategy: type-guard

Validate before calling

if (response == null || typeof response !== 'object' || !('id' in response)) {
  // inspect raw payload before calling assertTaskIdentity
}

Type guard

const hasTaskId = (t) => t != null && typeof t === 'object' && typeof t.id === 'string' && t.id.length > 0;

Try / catch

try {
  assertTaskIdentity(row, expectedId, 'task-get');
} catch (e) {
  console.error('Task row missing id; raw payload:', JSON.stringify(rawPayload));
  throw e;
}

Prevention

When it happens

Trigger: A slock command (get/update/delete/status) resolves successfully but the API response row `t` is null/undefined, is not an object, or lacks the `id` field, e.g. after an API schema change where the field was renamed or the endpoint returns an error payload shaped like success.

Common situations: Slock API version bump renaming `id` to `taskId`; a proxy returning an HTML error page parsed into an unexpected object; stale auth causing the server to return an empty payload with 200; unit fixtures missing the id field.

Related errors


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