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
- Paste a valid CAST AI API token into the token field/env var before invoking exchangeToken.
- Check upstream code for accidentally passing an empty string instead of the credential (e.g. process.env.KIMCHI_TOKEN unset).
- 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
- Always trim token input and check non-empty before calling exchangeToken.
- Disable the connect button in UI until the token field has content.
- Validate env vars at startup so empty credentials fail fast.
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
- No Codex access token available. Please re-authorize the con
- "Trae callback missing refreshToken"
- "Trae callback missing loginHost"
- Missing token
- Kiro tool input must be a JSON object
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/d064e91456a37545.
Report an issue: GitHub.