jlcodes99/cockpit-tools · error

SUB2API_ACCESS_TOKEN_MISSING

SUB2API_ACCESS_TOKEN_MISSING

Error message

SUB2API_ACCESS_TOKEN_MISSING

What it means

toSub2apiAccount throws SUB2API_ACCESS_TOKEN_MISSING when an OAuth-type account has no access_token: if the account is not an Agent Identity or API-key account (those paths return earlier with their own credentials), the OAuth fallback path requires tokens.access_token to build the sub2api item.

Source

Thrown at src/utils/codexExportFormats.ts:402

  };

  if (isCodexApiKeyAccount(account)) {
    return {
      ...base,
      type: 'apikey',
      credentials: buildSub2apiApiKeyCredentials(account),
    };
  }

  if (hasAgentIdentity(account)) {
    return {
      ...base,
      type: 'oauth',
      credentials: buildSub2apiCredentials(account),
    };
  }
  if (!account.tokens.access_token?.trim()) {
    throw new Error('SUB2API_ACCESS_TOKEN_MISSING');
  }

  const credentials = buildSub2apiCredentials(account);
  const extra = buildSub2apiExtra(account);
  const item: Sub2apiCreateAccountItem = {
    ...base,
    type: 'oauth',
    credentials,
    ...(extra ? { extra } : {}),
  };

  if (!account.tokens.refresh_token?.trim()) {
    const tokenExpiresAt = resolveAccessTokenExpiry(account);
    if (!tokenExpiresAt) {
      throw new Error('SUB2API_ACCESS_TOKEN_EXPIRY_MISSING');
    }
    item.expires_at = Math.floor(new Date(tokenExpiresAt).getTime() / 1000);
    item.auto_pause_on_expired = true;

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Re-run the OAuth login for the account so tokens.access_token is populated
  2. Verify the account's auth type matches its available credentials before export
  3. Skip accounts without access tokens in the export batch
  4. Refresh/re-authorize the account to restore tokens if they expired and were dropped

Example fix

// before
const item = toSub2apiAccount(oauthAccount); // throws
// after
if (oauthAccount.tokens?.access_token?.trim()) {
  const item = toSub2apiAccount(oauthAccount);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!account.tokens?.access_token?.trim()) {
  throw new Error('cannot export: missing access_token');
}

Type guard

function hasAccessToken(a: CodexAccount): boolean {
  return !!a.tokens?.access_token?.trim();
}

Try / catch

try {
  const item = toSub2apiAccount(account);
} catch (e) {
  if ((e as Error).message === 'SUB2API_ACCESS_TOKEN_MISSING') {
    // re-run OAuth or skip account
  }
}

Prevention

When it happens

Trigger: Calling toSub2apiAccount on an OAuth account whose tokens.access_token is undefined, empty, or whitespace, and which does not match the earlier agentIdentity/API-key branches.

Common situations: OAuth flow never completed so tokens were never stored; tokens cleared after a failed refresh; account data partially migrated between versions.

Related errors


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