jackwener/OpenCLI · error · CommandExecutionError

result.message || 'Failed to unsubscribe'

Error message

result.message || 'Failed to unsubscribe'

What it means

CommandExecutionError raised when the in-page unsubscribe command returned a non-auth error. The thrown message is result.message from the page evaluation when available, otherwise the fallback 'Failed to unsubscribe'. It wraps HTTP failures, missing Innertube config, or unparseable responses from the page-side API call.

Source

Thrown at clis/youtube/unsubscribe.js:72

          },
          body: JSON.stringify({ context, channelIds: [channelId] }),
        });

        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, channelId };
      })()
    `);
        if (result?.error === 'auth') {
            throw new AuthRequiredError('www.youtube.com');
        }
        if (result?.error) {
            throw new CommandExecutionError(result.message || 'Failed to unsubscribe');
        }
        return [{ status: 'success', message: 'Unsubscribed from: ' + (result.channelId || channelInput) }];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read e.message from the caught error to identify the concrete HTTP status or page-side failure.
  2. Re-run prepareYoutubeApiPage to ensure ytcfg/INNERTUBE_API_KEY are present before evaluating the command.
  3. Retry with backoff for transient 5xx/challenge responses and pace subscription changes to avoid bot detection.
  4. Verify the channel input resolves to a valid channel (valid channelId/browseId or existing subscription) before retrying.

Example fix

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

Strategy: try-catch

Validate before calling

const channelId = resolveChannelId(channelInput);
if (!channelId) throw new Error('Cannot resolve channel: ' + channelInput);

Try / catch

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

Prevention

When it happens

Trigger: result.error is truthy and not 'auth' — e.g. the unsubscribe fetch returned 'HTTP 400/403/500', INNERTUBE_API_KEY was missing from ytcfg.data_, or the channelId could not be resolved so the request was malformed.

Common situations: YouTube internal API rejecting with 400 (bad body/params) or 403 (bot detection/consent walls); channel identifier not resolving to a channelId/browseId; page not fully loaded so ytcfg lacks API key; transient network or 5xx inside the page.

Related errors


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