pear-devs/pear-desktop · error · Error
Token not initialized
Error message
Token not initialized
What it means
MusixMatch provider throws 'Token not initialized' when query() is invoked before the async token initialization has completed or if initialization failed to set a token. The method awaits this.initPromise and then checks this.token, so any init failure (e.g. 'Failed to get token') surfaces here as this error on subsequent API calls. It indicates the provider was never able to authenticate against the MusixMatch API.
Source
Thrown at src/plugins/synced-lyrics/providers/MusixMatch.ts:194
this.cookie = 'x-mxm-user-id=';
localStorage.removeItem(this.key);
this.initPromise = this.init();
await this.initPromise;
}
}
// god I love typescript generics, they're so useful
public async query<
T extends Endpoint,
R = {
header: { status_code: number };
body: T extends keyof typeof ResponseSchema
? z.infer<(typeof ResponseSchema)[T]>
: unknown;
},
>(endpoint: T, params: Params[T]): Promise<R> {
await this.initPromise;
if (!this.token) throw new Error('Token not initialized');
const url = `${this.baseUrl}${endpoint}`;
const clonedParams = new URLSearchParams(
Object.assign(
{
app_id: this.app_id,
format: 'json',
usertoken: this.token,
},
<Record<string, string>>params,
),
);
const [, json, headers] = await netFetch(`${url}?${clonedParams}`, {
headers: { Cookie: this.cookie },
});
View on GitHub (pinned to 1e2aac5706)
Solutions
- Check network access to the MusixMatch token endpoint and retry (call reinit()) once connectivity is restored.
- Clear the cached token entry in localStorage (this.key) and call reinit() to force a fresh token fetch.
- Inspect getToken()/savedTokenSchema parsing — if MusixMatch changed their page structure, update the token extraction logic.
- Ensure you await the provider's initialization (or the first query) before showing results, so init errors surface clearly instead of this secondary error.
Example fix
// before
const lyrics = await provider.query('matcher.lyrics.get', { q_track: '...' });
// after
try {
const lyrics = await provider.query('matcher.lyrics.get', { q_track: '...' });
} catch (e) {
if (e instanceof Error && e.message === 'Token not initialized') {
await provider.reinit();
// retry once after re-initialization
}
} Defensive patterns
Strategy: retry
Validate before calling
// before querying, ensure the provider initialized successfully
await provider.initPromise; // rethrows init failure early, or:
if (!provider.token) {
await provider.reinit();
} Type guard
const isTokenNotInitialized = (e: unknown): boolean => e instanceof Error && e.message === 'Token not initialized';
Try / catch
try {
const res = await provider.query('matcher.subtitle.get', params);
} catch (e) {
if (isTokenNotInitialized(e)) {
await provider.reinit();
return provider.query('matcher.subtitle.get', params); // one retry
}
throw e;
} Prevention
- Always await the provider's init (or initPromise) before the first query.
- Treat consecutive failures as a signal to disable the MusixMatch provider and fall back to other providers.
- Clear the cached localStorage token when debugging init issues.
When it happens
Trigger: Calling any lyrics lookup (this.data()/query()) before init() finishes, after init() threw 'Failed to get token', or after the cached token was removed from localStorage and reinit failed (network error or changed token endpoint).
Common situations: Offline or proxied environment blocking the token fetch, MusixMatch changing their token scraping endpoint/HTML structure, corrupted localStorage entry under this.key, or racing the provider's construction against an immediate query call.
Related errors
AI-assisted analysis of pear-devs/pear-desktop@1e2aac5706 (2026-08-27).
Data as JSON: /api/errors/56901dbc0b46f970.
Report an issue: GitHub.