decolua/9router · error · Error

cosy: auth token is empty

Error message

cosy: auth token is empty

What it means

Companion guard to the userId check: buildCosyHeaders also requires creds.authToken, which is used to authenticate/derive the signed headers. It throws immediately when the token is missing or empty. Without it, requests to Cosy upstreams would fail authentication anyway, so the library fails fast client-side.

Source

Thrown at open-sse/shared/qoder/cosy.js:118

}

/**
 * Build the full Cosy-* header set for a single Qoder request.
 *
 * @param {Buffer|Uint8Array|string} body  The exact bytes that will be sent.
 *   For GET requests pass an empty Buffer / "".
 * @param {string} requestUrl              Full request URL (used for sigPath).
 * @param {object} creds
 * @param {string} creds.userId            Stable Qoder user id.
 * @param {string} creds.authToken         Device access token (`dt-...`).
 * @param {string} [creds.name]            Display name (optional).
 * @param {string} [creds.email]           Email (optional, can be empty).
 * @param {string} [creds.machineId]       Persisted machine UUID.
 * @returns {Record<string, string>} Header map ready to merge onto fetch().
 */
export function buildCosyHeaders(body, requestUrl, creds) {
  if (!creds?.userId) throw new Error("cosy: user id is empty");
  if (!creds?.authToken) throw new Error("cosy: auth token is empty");

  const bodyBuf = Buffer.isBuffer(body)
    ? body
    : typeof body === "string"
      ? Buffer.from(body, "latin1")
      : Buffer.from(body || []);

  const { cosyKey, info } = encryptUserInfo({
    uid: creds.userId,
    security_oauth_token: creds.authToken,
    name: creds.name || "",
    aid: "",
    email: creds.email || "",
  });

  const timestamp = String(Math.floor(Date.now() / 1000));
  const requestId = uuidv4();

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Re-run the Cosy/Qoder login to obtain and store a fresh authToken
  2. Verify the account record's authToken field is populated and non-empty
  3. Check token-refresh code is not writing null/empty on refresh failure
  4. Confirm the credentials object passed in maps the token to creds.authToken

Example fix

// before
const creds = { userId: account.uid, authToken: account.access_token /* undefined after rename */ };
// after
const creds = { userId: account.uid, authToken: account.authToken };
if (!creds.authToken) await relogin(account);
Defensive patterns

Strategy: validation

Validate before calling

if (!creds?.authToken) {
  throw new Error("Cosy authToken missing — re-run the Qoder/Cosy login flow");
}

Type guard

function hasCosyAuthToken(c) { return typeof c?.authToken === "string" && c.authToken.length > 0; }

Try / catch

try {
  headers = buildCosyHeaders(body, url, creds);
} catch (e) {
  if (/auth token is empty/.test(e.message)) {
    creds = await refreshOrReloginCosy(account);
    headers = buildCosyHeaders(body, url, creds);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling execute/headers with creds lacking authToken — e.g. after a login flow that stored userId but no token, a cleared/expired token wiped from storage, or an account record imported without the token field.

Common situations: Token revoked upstream and purged locally; token-refresh logic wrote null; account created from a partial config; env/config key renamed so the token is read as undefined.

Related errors


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