jackwener/OpenCLI · error · CommandExecutionError

${label} returned a non-JSON response

Error message

${label} returned a non-JSON response

What it means

atlassianRequest throws this when the HTTP response was OK (2xx) but the body could not be parsed as JSON — the parsed result is a string. The Atlassian REST API is expected to return JSON, so a string body almost always means something other than the API answered (HTML login/SSO page, proxy intercept, or a wrong URL that serves HTML with 200).

Source

Thrown at clis/_atlassian/shared.js:218

        );
    }
    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));
        }
    }
    const s = qs.toString();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the base URL — it must be the Atlassian site root (e.g. https://example.atlassian.net) or a reachable REST base, not a login/portal page.
  2. Re-run with curl to see the actual HTML body and identify who produced it (SSO provider, proxy, captive portal).
  3. Whitelist the tool in the corporate proxy or run from a network without the intercepting proxy.
  4. For Data Center, ensure the deployment setting matches the instance so the correct REST path prefix is used.
  5. If an SSO redirect is unavoidable, use a personal access token / API token so requests authenticate before the SSO page is served.

Example fix

// before (base URL points at a portal that serves HTML 200)
ATLASSIAN_BASE_URL=https://intranet.corp.com/confluence-home
// after
ATLASSIAN_BASE_URL=https://example.atlassian.net
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: verify the endpoint returns JSON before real work
const res = await fetch(`${baseUrl}/rest/api/space?limit=1`, { headers: authHeaders() });
const ct = res.headers.get('content-type') || '';
if (!ct.includes('application/json')) throw new Error('Endpoint did not return JSON — check base URL/proxy');

Type guard

function isJsonObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }

Try / catch

try {
  const data = await cmd(args);
} catch (e) {
  if (/non-JSON response/.test(e.message)) {
    console.error('Got HTML instead of JSON — SSO/proxy intercept or wrong base URL. Inspect with curl.');
  } else throw e;
}

Prevention

When it happens

Trigger: The base URL points at a server that returns HTML with status 200 — e.g. an SSO/login redirect, a captive proxy, an expired session page, or a typo'd base URL hitting a website instead of the REST endpoint.

Common situations: Corporate proxy injecting an authentication page; ATLASSIAN_BASE_URL missing the /wiki or /rest path context so a portal page is served; VPN/captive portal returning an HTML block page; pointing cloud credentials at a self-hosted instance whose login screen returns 200 HTML.

Related errors


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