decolua/9router · error · Error

"Missing Kimchi token"

Error message

"Missing Kimchi token"

What it means

Thrown by the Kimchi (CAST AI) OAuth provider's exchangeToken when the user-supplied token is empty or whitespace-only after trimming. The provider requires a manually pasted access token and refuses to send an empty Bearer credential upstream. It is a guard against pointless validation calls and misleading downstream 401s.

Source

Thrown at src/lib/oauth/providers/kimchi.js:17

import { KIMCHI_CONFIG } from "../constants/oauth.js";

const kimchi = {
  config: KIMCHI_CONFIG,
  flowType: "browser_token",
  buildAuthUrl: (config, redirectUri, state) => {
    const baseUrl = (config.webAppUrl || "https://app.kimchi.dev").replace(/\/+$/, "");
    const params = new URLSearchParams({
      callback: redirectUri,
      state,
    });
    return `${baseUrl}/cli-auth?${params.toString()}`;
  },
  exchangeToken: async (config, token) => {
    const accessToken = String(token || "").trim();
    if (!accessToken) {
      throw new Error("Missing Kimchi token");
    }

    const validationUrl = config.validationUrl || "https://api.cast.ai/v1/llm/openai/supported-providers";
    const validationRes = await fetch(validationUrl, {
      method: "GET",
      headers: {
        Accept: "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
    });
    if (!validationRes.ok) {
      throw new Error(`Kimchi token validation failed: ${validationRes.status}`);
    }

    let userInfo = {};
    if (config.userInfoUrl) {
      try {
        const userRes = await fetch(config.userInfoUrl, {

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Paste a valid CAST AI API token into the token field/env var before invoking exchangeToken.
  2. Check upstream code for accidentally passing an empty string instead of the credential (e.g. process.env.KIMCHI_TOKEN unset).
  3. Add a pre-call check: if (!token || !token.trim()) show a user-facing prompt instead of calling exchangeToken.

Example fix

// before
await kimchiProvider.exchangeToken(config, userTokenInput);
// after
if (!userTokenInput || !userTokenInput.trim()) {
  throw new Error('Please paste your CAST AI token first');
}
await kimchiProvider.exchangeToken(config, userTokenInput.trim());
Defensive patterns

Strategy: validation

Validate before calling

function hasKimchiToken(token) {
  return typeof token === 'string' && token.trim().length > 0;
}
if (!hasKimchiToken(rawToken)) throw new Error('Provide a CAST AI token before connecting');

Type guard

const isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
  await provider.exchangeToken(config, token);
} catch (e) {
  if (e.message === 'Missing Kimchi token') {
    // prompt user to paste token
  } else throw e;
}

Prevention

When it happens

Trigger: Calling exchangeToken (the token-exchange step of Kimchi login) with token = null, undefined, "", or a string of only spaces — e.g. the UI field was left blank, clipboard paste failed, or the config value for the token was never set.

Common situations: User clicks 'connect' before pasting a token; an automation passes an unset env var; a stored credential was deleted and an empty string was persisted; trimming stripped a whitespace-only paste.

Related errors


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