jackwener/OpenCLI · error · CommandExecutionError

result.message || 'Failed to remove like'

Error message

result.message || 'Failed to remove like'

What it means

CommandExecutionError raised when the in-page unlike command returned a generic error that was not auth-related. The thrown message is result.message when the page evaluation provided one, otherwise the fallback 'Failed to remove like'. It wraps any non-auth failure (HTTP error, missing config, unexpected response shape) from the page-side API call.

Source

Thrown at clis/youtube/unlike.js:63

          },
          body: JSON.stringify({ context, target: { videoId: ${JSON.stringify(videoId)} } }),
        });

        if (resp.status === 401 || resp.status === 403) return { error: 'auth', message: 'Not logged in' };
        if (!resp.ok) {
          const body = await resp.json().catch(() => ({}));
          const errStatus = body?.error?.status || '';
          if (errStatus === 'UNAUTHENTICATED') return { error: 'auth', message: 'Not logged in' };
          return { error: 'http', message: 'HTTP ' + resp.status + (errStatus ? ' ' + errStatus : '') };
        }
        return { ok: true };
      })()
    `);
        if (result?.error === 'auth') {
            throw new AuthRequiredError('www.youtube.com');
        }
        if (result?.error) {
            throw new CommandExecutionError(result.message || 'Failed to remove like');
        }
        return [{ status: 'success', message: 'Unliked: ' + videoId }];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect result.message in the caught error to see the underlying HTTP status or page-side failure detail.
  2. Re-run prepareYoutubeApiPage so the page (and ytcfg/INNERTUBE_API_KEY) is fully loaded before evaluating.
  3. Retry after a delay — transient 5xx or bot-detection challenges often resolve; consider slower pacing between like/unlike calls.
  4. Verify the video URL parses to a valid videoId and the video still exists; log in if the error turns out to be auth-flavored.

Example fix

// before
await unlike(kwargs); // throws CommandExecutionError with fallback message
// after
try {
  await unlike(kwargs);
} catch (e) {
  if (e.name === 'CommandExecutionError') {
    console.error('unlike failed:', e.message); // e.g. 'HTTP 403 ...'
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await unlike({ url });
} catch (e) {
  if (e.name === 'CommandExecutionError') {
    if (/HTTP 5\d\d/.test(e.message)) return retryWithBackoff(() => unlike({ url }));
    console.error('unlike failed:', e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: result.error is truthy and not 'auth' — e.g. the internal removelike fetch returned a non-OK HTTP status ('HTTP 400/403/500'), INNERTUBE_API_KEY was absent from ytcfg, or the response JSON could not be interpreted.

Common situations: YouTube internal API returning 400/403 (bot detection, consent walls, region blocks); ytcfg.data_ missing INNERTUBE_API_KEY because the page did not fully load; videoId invalid or video in unexpected state; network failure or timeout inside page.evaluate.

Related errors


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