mastra-ai/mastra · error

Kimi For Coding credentials have an invalid device ID. Pleas

Error message

Kimi For Coding credentials have an invalid device ID. Please reconnect the account.

What it means

getKimiCodingDeviceHeaders builds the device headers (including X-Msh-Device-Id) required by Kimi For Coding, but first validates the stored device ID against DEVICE_ID_PATTERN. If the persisted deviceId fails that pattern (wrong shape/characters/length), the library throws and asks the user to reconnect, because a malformed device ID would be rejected server-side anyway.

Source

Thrown at mastracode/sdk/src/auth/providers/kimi-coding.ts:44

const KIMI_DEVICE_DETAILS = {
  'X-Msh-Platform': 'mastracode',
  'X-Msh-Version': asciiHeaderValue(getCurrentVersion()),
  'X-Msh-Device-Name': asciiHeaderValue(hostname()),
  'X-Msh-Device-Model': asciiHeaderValue(`${platform()} ${arch()}`),
  'X-Msh-Os-Version': asciiHeaderValue(release()),
};

export function createKimiCodingDeviceId(): string {
  return randomUUID().replaceAll('-', '');
}

export function isKimiCodingDeviceId(value: unknown): value is string {
  return typeof value === 'string' && DEVICE_ID_PATTERN.test(value);
}

export function getKimiCodingDeviceHeaders(deviceId: string): Record<string, string> {
  if (!isKimiCodingDeviceId(deviceId)) {
    throw new Error('Kimi For Coding credentials have an invalid device ID. Please reconnect the account.');
  }
  return { ...KIMI_DEVICE_DETAILS, 'X-Msh-Device-Id': deviceId };
}

function requestSignal(signal?: AbortSignal): AbortSignal {
  const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);
  return signal ? AbortSignal.any([timeout, signal]) : timeout;
}

function trustedHttpUrl(value: unknown): string | null {
  if (typeof value !== 'string' || !value) return null;
  try {
    const url = new URL(value);
    return url.protocol === 'https:' ? url.href : null;
  } catch {
    return null;
  }
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Reconnect the account: re-run the Kimi For Coding device login flow to mint fresh credentials with a valid device ID
  2. Inspect the stored credentials and delete/clear the invalid deviceId entry so a fresh one is generated
  3. Check for concurrent writers or truncation of the credentials file; back up before migrating

Example fix

// before (corrupted stored credential)
{"deviceId": "", "access": "eyJ..."}
// after: delete and re-login
await login('kimi-coding'); // regenerates a pattern-valid device ID
Defensive patterns

Strategy: validation

Validate before calling

const DEVICE_ID_PATTERN = /^[A-Za-z0-9-]+$/; // match the library's expectation loosely
const creds = await loadCredentials();
if (!creds || !isKimiCodingDeviceId(creds.deviceId)) {
  await login('kimi-coding'); // re-mint valid credentials before any request
}

Type guard

function isKimiCodingDeviceId(value: unknown): value is string {
  return typeof value === 'string' && DEVICE_ID_PATTERN.test(value);
}

Try / catch

try {
  headers = getKimiCodingDeviceHeaders(creds.deviceId);
} catch (err) {
  if (err instanceof Error && err.message.includes('invalid device ID')) {
    await login('kimi-coding'); // reconnect to regenerate a valid device ID
    headers = getKimiCodingDeviceHeaders(creds.deviceId);
  } else throw err;
}

Prevention

When it happens

Trigger: Loading Kimi For Coding credentials whose deviceId field is corrupted, empty, manually edited, produced by an older/buggy SDK version, or written by a different tool with a different ID format, then calling getKimiCodingDeviceHeaders (via deviceHeaders/response paths).

Common situations: Hand-editing or migrating the credentials file between machines/tools; a partial or failed write during a previous login; format change of the device ID between library versions.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/bf4734cd3198586a. Report an issue: GitHub.