jlcodes99/cockpit-tools · error

Trae OAuth start 响应缺少关键字段

Error message

Trae OAuth start 响应缺少关键字段

What it means

normalizeTraeOAuthStartResponse validates the Trae device-authorization start response. The device-link flow cannot proceed without loginId and verificationUri (camelCase or snake_case); if both lookups yield empty values the library throws this error ('Trae OAuth start response missing key fields') rather than returning a half-usable session.

Solutions

  1. Inspect the raw HTTP response body for loginId and verificationUri
  2. Confirm the request hits the correct Trae OAuth endpoint (check base URL/proxy config)
  3. Update the app so client and backend OAuth contracts match (both naming styles are handled)
  4. Retry the start call; if reproducible, capture the payload and report it

Example fix

// before
const session = await traeOauthLoginStart();
// after
try {
  const session = await traeOauthLoginStart();
} catch (e) {
  console.error('Trae OAuth start failed:', e.message, rawBody);
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const raw = await res.clone().json();
if (!(raw?.loginId ?? raw?.login_id) || !(raw?.verificationUri ?? raw?.verification_uri)) {
  console.error('Trae OAuth start body malformed:', raw);
}

Type guard

function hasOAuthStartFields(v: unknown): v is { loginId: string; verificationUri: string } {
  const r = v as any;
  return !!(r?.loginId ?? r?.login_id) && !!(r?.verificationUri ?? r?.verification_uri);
}

Try / catch

try {
  const session = await traeOauthLoginStart();
} catch (e) {
  if (String(e.message).includes('缺少关键字段')) {
    showRetryDialog('Trae login could not start — verify endpoint/proxy and retry');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling traeOauthLoginStart when the backend response omits loginId or verificationUri/verification_uri — an error body returned with HTTP 200, a gateway/proxy altering the payload, or an API schema change between client and server versions.

Common situations: Trae service outage returning error JSON, misconfigured base URL pointing at a wrong endpoint, or stale app version after a backend field rename.

Related errors


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

Appendix: source

Thrown at src/services/traeService.ts:31

}

type TraeOAuthStartResponseRaw = Partial<TraeOAuthStartResponse> & {
  login_id?: string;
  verification_uri?: string;
  expires_in?: number;
  interval_seconds?: number;
  callback_url?: string | null;
};

function normalizeTraeOAuthStartResponse(raw: TraeOAuthStartResponseRaw): TraeOAuthStartResponse {
  const loginId = raw.loginId ?? raw.login_id ?? '';
  const verificationUri = raw.verificationUri ?? raw.verification_uri ?? '';
  const expiresIn = Number(raw.expiresIn ?? raw.expires_in ?? 0);
  const intervalSeconds = Number(raw.intervalSeconds ?? raw.interval_seconds ?? 0);
  const callbackUrl = raw.callbackUrl ?? raw.callback_url ?? null;

  if (!loginId || !verificationUri) {
    throw new Error('Trae OAuth start 响应缺少关键字段');
  }

  return {
    loginId,
    verificationUri,
    expiresIn: Number.isFinite(expiresIn) && expiresIn > 0 ? expiresIn : 600,
    intervalSeconds: Number.isFinite(intervalSeconds) && intervalSeconds > 0 ? intervalSeconds : 1,
    callbackUrl,
  };
}

export async function listTraeAccounts(): Promise<TraeAccount[]> {
  return await invoke('list_trae_accounts');
}

export async function deleteTraeAccount(accountId: string): Promise<void> {
  return await invoke('delete_trae_account', { accountId });
}

View on GitHub (pinned to 1ed8b77992)