jlcodes99/cockpit-tools · error

readBundleMessage(msg) ?? readBundleMessage(message) ?? read

Error message

readBundleMessage(msg) ?? readBundleMessage(message) ?? readBundleMessage(error) ?? messages.empty

What it means

The imported JSON parsed to an API-style envelope containing a 'code' field that is not 200 (or "200"). The parser surfaces the API's own error message from msg/message/error; messages.empty is the fallback when none of those fields carry a usable string (line 391). This is the remote endpoint reporting failure, not a local syntax problem.

Source

Thrown at src/hooks/useProviderAccountsPage.ts:391

    if (platformId === 'codex') {
      try {
        const rawRefreshTokenItems = parseCodexRawRefreshTokenItems(rawContent, messages);
        if (rawRefreshTokenItems && rawRefreshTokenItems.length > 0) {
          return rawRefreshTokenItems;
        }
      } catch (error) {
        throw error;
      }
    }

    if (lineDelimitedError) throw lineDelimitedError;
    throw new Error(messages.invalidJson);
  }

  if (parsed && typeof parsed === 'object' && 'code' in parsed) {
    const code = (parsed as { code?: unknown }).code;
    if (code !== 200 && code !== '200') {
      throw new Error(
        readBundleMessage((parsed as { msg?: unknown }).msg) ??
          readBundleMessage((parsed as { message?: unknown }).message) ??
          readBundleMessage((parsed as { error?: unknown }).error) ??
          messages.empty,
      );
    }
  }

  const root =
    parsed && typeof parsed === 'object' && 'data' in parsed
      ? (parsed as { data?: unknown }).data
      : parsed;

  if (typeof root === 'string') {
    return resolveExternalImportBundleItems(root, platformId, messages);
  }

  if (Array.isArray(root)) {

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Re-fetch the export from the API with valid authentication so code is 200
  2. Read the actual HTTP status/headers instead of pasting the error body
  3. If you control the endpoint, include a non-empty msg or message field so users see the real reason
  4. Paste only the data payload rather than the whole error envelope

Example fix

// before
{"code":401,"msg":""}
// after (successful export)
{"code":200,"data":{"items":[{"refresh_token":"rt_a"}]}}
Defensive patterns

Strategy: try-catch

Validate before calling

const bundle: unknown = JSON.parse(content);
if (bundle && typeof bundle === 'object' && 'code' in bundle) {
  const b = bundle as { code?: unknown; msg?: unknown; message?: unknown };
  if (b.code !== 200 && b.code !== '200') {
    throw new Error(`API error (code ${String(b.code)}): ${String(b.msg ?? b.message ?? 'unknown')}`);
  }
}

Type guard

const isSuccessfulEnvelope = (v: unknown): boolean =>
  !!v && typeof v === 'object' && !Array.isArray(v) &&
  ((v as { code?: unknown }).code === 200 || (v as { code?: unknown }).code === '200');

Try / catch

try {
  items = resolveExternalImportBundleItems(content, platformId, messages);
} catch (e) {
  if (e instanceof Error && e.message !== messages.invalidJson && e.message !== messages.noItems) {
    showRemoteApiError(e.message);
  }
}

Prevention

When it happens

Trigger: Pasting a raw HTTP API response body whose envelope has code != 200 and no msg/message/error string field (or only empty strings).

Common situations: Copying an error response (401/404/500 body) instead of the success payload; API requires auth so it returned {code:401}; older API versions using different error field names; rate-limit or maintenance responses.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/bd9fd6f7a11f3567. Report an issue: GitHub.