jackwener/OpenCLI · error · CliError

AUTH_CORRUPTED

AUTH_CORRUPTED

Error message

Token file is corrupted. Run: opencli spotify auth

What it means

getToken throws AUTH_CORRUPTED when a token file exists but is missing required fields: access_token, refresh_token, or a positive numeric expires_at. The CLI treats a partially-written or malformed token file as unusable because it can neither call the API nor silently refresh, and points the user at re-auth.

Source

Thrown at clis/spotify/spotify.js:72

    if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new CliError('REFRESH_FAILED', err?.error_description || `Token refresh failed (${res.status})`);
    }
    const data = await res.json();
    const tokens = {
        access_token: data.access_token,
        refresh_token: data.refresh_token || refreshToken,
        expires_at: Date.now() + data.expires_in * 1000,
    };
    saveTokens(tokens);
    return tokens.access_token;
}
async function getToken() {
    const tokens = loadTokens();
    if (!tokens)
        throw new CliError('AUTH_REQUIRED', 'Not authenticated. Run: opencli spotify auth');
    if (!tokens.access_token || !tokens.refresh_token || !(tokens.expires_at > 0)) {
        throw new CliError('AUTH_CORRUPTED', 'Token file is corrupted. Run: opencli spotify auth');
    }
    if (Date.now() > tokens.expires_at - 60_000)
        return refreshAccessToken(tokens.refresh_token);
    return tokens.access_token;
}
// ── Spotify API helper ────────────────────────────────────────────────────────
async function api(method, path, body) {
    const token = await getToken();
    const res = await fetch(`https://api.spotify.com/v1${path}`, {
        method,
        headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
        body: body ? JSON.stringify(body) : undefined,
    });
    if (res.status === 204 || res.status === 202)
        return null;
    if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new CliError('API_ERROR', err?.error?.message || `Spotify API error ${res.status}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Delete the token file and run opencli spotify auth to recreate it cleanly.
  2. Inspect the token file and confirm it contains access_token, refresh_token, and numeric expires_at.
  3. Check for concurrent writers (cron jobs, scripts) that may truncate the file.

Example fix

// before: corrupted file
{"access_token": ""}  // AUTH_CORRUPTED
// after: re-authenticate
rm ~/.opencli/spotify-tokens.json && opencli spotify auth
Defensive patterns

Strategy: validation

Validate before calling

const t = loadTokens();
const valid = !!t && typeof t.access_token === 'string' && t.access_token.length > 0
  && typeof t.refresh_token === 'string' && t.refresh_token.length > 0
  && typeof t.expires_at === 'number' && t.expires_at > 0;
if (!valid) { console.error('Token file invalid; delete it and run: opencli spotify auth'); }

Type guard

function isCompleteTokens(t) {
  return !!t && typeof t === 'object'
    && typeof t.access_token === 'string' && t.access_token.length > 0
    && typeof t.refresh_token === 'string' && t.refresh_token.length > 0
    && typeof t.expires_at === 'number' && t.expires_at > 0;
}

Try / catch

try {
  await spotifyCommand(args);
} catch (e) {
  if (e.code === 'AUTH_CORRUPTED') {
    fs.rmSync(TOKEN_PATH, { force: true });
    await runAuthFlow();
    await spotifyCommand(args);
  } else throw e;
}

Prevention

When it happens

Trigger: loadTokens() returns an object lacking any of access_token, refresh_token, or expires_at > 0 — e.g. a hand-edited, truncated, or partially-written token file, or a file written by an older CLI version with a different schema.

Common situations: Manual editing of the token JSON; disk-full or crash mid-write leaving truncated JSON; downgrading/upgrading the CLI to a version with a different token schema; another tool overwriting the token file.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/351f28188309f37d. Report an issue: GitHub.