jackwener/OpenCLI · error · CommandExecutionError

${label} returned HTTP ${resp.status}: ${summarizeApiError(p

Error message

${label} returned HTTP ${resp.status}: ${summarizeApiError(parsed, resp.statusText)}

What it means

atlassianRequest throws this when the Atlassian REST API responds with a non-2xx, non-429 HTTP status. The API's parsed body (or the status text) is summarized into the message so the developer can see what Atlassian rejected and why. This is the generic upstream-API-failure path for all Atlassian (Jira/Confluence) commands.

Source

Thrown at clis/_atlassian/shared.js:215

            config.baseUrl,
            `${label} returned HTTP 403: ${summarizeApiError(parsed, 'forbidden')}`,
            'The authenticated user lacks permission for this Jira issue, Confluence page, or space.',
        );
    }
    if (resp.status === 404) {
        throw new EmptyResultError(label, `Atlassian returned 404 for ${url}.`);
    }
    if (resp.status === 409) {
        throw new CommandExecutionError(
            `${label} returned HTTP 409: ${summarizeApiError(parsed, 'version conflict')}`,
            'Reload the current Confluence page version and retry the update.',
        );
    }
    if (resp.status === 429) {
        throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`, 'Wait and retry with a smaller limit.');
    }
    if (!resp.ok) {
        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}: ${summarizeApiError(parsed, resp.statusText)}`);
    }
    if (typeof parsed === 'string') {
        throw new CommandExecutionError(
            `${label} returned a non-JSON response`,
            'Expected Atlassian REST API JSON. Check the base URL and whether an HTML login, SSO, or proxy page was returned.',
        );
    }
    return parsed;
}

export function queryString(params) {
    const qs = new URLSearchParams();
    for (const [key, value] of Object.entries(params)) {
        if (value === undefined || value === null || value === '') continue;
        if (Array.isArray(value)) {
            for (const item of value) qs.append(key, String(item));
        } else {
            qs.set(key, String(value));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the summarized API error in the message; it usually names the exact Atlassian-side reason (e.g. 401 vs 404).
  2. For 401/403, regenerate the API token and verify ATLASSIAN_EMAIL/ATLASSIAN_API_TOKEN (cloud) or ATLASSIAN_PERSONAL_TOKEN (datacenter) are set correctly.
  3. For 404, verify the base URL resolves to the correct site and that the target page/issue/space ID exists and is visible to the authenticated user.
  4. For 400, validate the CQL/JQL query or request body passed to the command.
  5. For 5xx, check the Atlassian status page and retry later.

Example fix

// before (stale token)
ATLASSIAN_API_TOKEN=old_token opencli jira search "project = DEMO"
// after
# regenerate token at id.atlassian.com, then:
ATLASSIAN_EMAIL=me@corp.com ATLASSIAN_API_TOKEN=<new_token> opencli jira search "project = DEMO"
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling
if (!process.env.ATLASSIAN_BASE_URL) throw new Error('ATLASSIAN_BASE_URL not set');
if (!process.env.ATLASSIAN_API_TOKEN && !process.env.ATLASSIAN_PERSONAL_TOKEN) throw new Error('No Atlassian credentials configured');

Type guard

function isHttpError(e) { return e instanceof Error && /returned HTTP \d{3}/.test(e.message); }

Try / catch

try {
  const data = await cmd(args);
} catch (e) {
  const m = e.message.match(/returned HTTP (\d+):(sha)?/);
  const status = m ? Number(m[1]) : 0;
  if (status === 401 || status === 403) fixCredentials();
  else if (status === 404) console.error('Resource not found — check ID and base URL');
  else if (status >= 500) retryWithBackoff();
  else throw e;
}

Prevention

When it happens

Trigger: Any atlassianRequest call where resp.ok is false and resp.status !== 429: 401/403 (bad or expired API token), 404 (wrong site URL, deleted page/issue ID, wrong deployment mode), 400 (malformed CQL/JQL or body), 5xx (Atlassian outage).

Common situations: Expired or revoked Atlassian API token; using an email/API-token pair against a Data Center instance expecting PAT (or vice versa); typo'd ATLASSIAN_BASE_URL pointing at a non-Atlassian host; requesting a page ID that was moved to trash; CQL syntax errors.

Related errors


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