decolua/9router · error · Error

`CodeBuddy state error: ${data.msg || "missing state/authUrl

Error message

`CodeBuddy state error: ${data.msg || "missing state/authUrl"}`

What it means

CodeBuddy (CN) returned HTTP 200 but an application-level error: the JSON envelope's code !== 0, or data.data.state / data.data.authUrl is missing. The provider maps the envelope's msg field into this Error, falling back to 'missing state/authUrl' when msg is absent. Unlike [201], the HTTP layer succeeded — the API refused the request in its payload.

Source

Thrown at src/lib/oauth/providers/codebuddy-cn.js:28

  requestDeviceCode: async (config) => {
    const response = await fetch(`${config.stateUrl}?platform=${config.platform}`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
        "User-Agent": config.userAgent,
        "X-Requested-With": "XMLHttpRequest",
        "X-Domain": "copilot.tencent.com",
        "X-No-Authorization": "true",
        "X-No-User-Id": "true",
        "X-Product": "SaaS",
      },
      body: "{}",
    });
    if (!response.ok) throw new Error(`CodeBuddy state request failed: ${await response.text()}`);
    const data = await response.json();
    if (data.code !== 0 || !data.data?.state || !data.data?.authUrl) {
      throw new Error(`CodeBuddy state error: ${data.msg || "missing state/authUrl"}`);
    }
    return {
      device_code: data.data.state,
      verification_uri: data.data.authUrl,
      user_code: "",
      interval: config.pollInterval / 1000,
      _isCodeBuddy: true,
    };
  },
  pollToken: async (config, deviceCode) => {
    // CodeBuddy polls the token endpoint via GET with the state as a query
    // param (not POST/body) — matches the official CLI's /v2/plugin/auth/token?state=...
    const response = await fetch(`${config.tokenUrl}?state=${encodeURIComponent(deviceCode)}`, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "User-Agent": config.userAgent,
        "X-Requested-With": "XMLHttpRequest",

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Read data.msg in the error message — it states the API's own reason.
  2. Log the full response JSON and compare against the expected envelope {code:0, data:{state, authUrl}}; update field paths if the schema changed.
  3. Retry the state request — transient application-level errors often clear.
  4. Check for a CodeBuddy client/API update and bump the provider config accordingly.

Example fix

// before
if (data.code !== 0 || !data.data?.state || !data.data?.authUrl) {
  throw new Error(`CodeBuddy state error: ${data.msg || "missing state/authUrl"}`);
}
// after
if (data.code !== 0 || !data.data?.state || !data.data?.authUrl) {
  throw new Error(`CodeBuddy state error: ${data.msg || "missing state/authUrl"} (code=${data.code}, keys=${Object.keys(data.data || {})})`);
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the envelope before relying on it
const data = await response.json();
if (typeof data.code !== "number" || !data.data?.state || !data.data?.authUrl) {
  console.error("CodeBuddy CN envelope:", JSON.stringify(data).slice(0, 1000));
}

Type guard

function isCodeBuddyStateEnvelope(v) {
  return !!v && typeof v === "object" && v.code === 0 &&
    typeof v.data === "object" && v.data !== null &&
    typeof v.data.state === "string" && v.data.state.length > 0 &&
    typeof v.data.authUrl === "string" && v.data.authUrl.startsWith("http");
}

Try / catch

try {
  const s = await startCodeBuddyFlow();
} catch (err) {
  if (String(err.message).includes("CodeBuddy state error")) {
    // application-level: msg carries the API reason; do not blind-retry
    console.error("CodeBuddy CN API refused state request:", err.message);
  } else throw err;
}

Prevention

When it happens

Trigger: Successful POST to the state endpoint whose body parses to { code: non-zero } or lacks data.state/data.authUrl — e.g. service degraded but returning 200, API version change renaming fields, or region/account restrictions encoded in code/msg.

Common situations: CodeBuddy updated their response schema (state/authUrl renamed or nested differently); account/region not permitted to use device login; server returns {code:500,...} with a Chinese-language msg; proxy altering the response.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/be0b3884d3d65f38. Report an issue: GitHub.