pear-devs/pear-desktop · error · Error
Failed to extract lyrics from preloaded state.
Error message
Failed to extract lyrics from preloaded state.
What it means
The Genius lyrics provider fetches the song page and extracts lyrics from its __PRELOADED_STATE__ JSON embedded in the page. If the expected lyrics HTML fragment cannot be found in that state, it throws 'Failed to extract lyrics from preloaded state.' — unless the page indicates the song is unreleased, in which case it returns null.
Source
Thrown at src/plugins/synced-lyrics/providers/LyricsGenius.ts:82
},
) as HTMLScriptElement;
const preloadedState = preloadedStateScript.textContent?.match(
preloadedStateRegex,
)?.[1]?.replace(/\\"/g, '"');
const lyricsHtml = preloadedState?.match(preloadHtmlRegex)?.[1]
?.replace(/\\\//g, '/')
?.replace(/\\\\/g, '\\')
?.replace(/\\n/g, '\n')
?.replace(/\\'/g, "'")
?.replace(/\\"/g, '"');
const hasUnreleasedPlaceholder = preloadedState &&
/lyricsPlaceholderReason.{1,5}unreleased/.test(preloadedState);
if (!lyricsHtml) {
if (hasUnreleasedPlaceholder) return null;
throw new Error('Failed to extract lyrics from preloaded state.');
}
const lyricsDoc = this.domParser.parseFromString(lyricsHtml, 'text/html');
const lyrics = lyricsDoc.body.innerText;
if (lyrics.trim().toLowerCase().replace(/[[\]]/g, '') === 'instrumental') {
return null;
}
return {
title: closestHit.result.title,
artists: closestHit.result.primary_artists.map(({ name }) => name),
lyrics,
};
}
}
interface LyricsGeniusSearch {View on GitHub (pinned to 1e2aac5706)
Solutions
- Update the synced-lyrics plugin — Genius scraping breaks periodically and gets patched
- Fall back to LRCLib/Megalobiz when this error occurs
- Return null (no lyrics) in the UI rather than crashing the lyrics panel
- If it reproduces for all tracks, suspect bot-blocking and verify genius.com loads normally in a browser
Example fix
// before
const r = await genius.search(info);
// after
try { return await genius.search(info); }
catch (e) {
if (!/preloaded state/.test(e.message)) throw e;
return await lrclib.search(info);
} Defensive patterns
Strategy: fallback
Try / catch
try { return await genius.search(info); } catch (e) { if (!/preloaded state/.test(e.message)) throw e; return await lrclib.search(info); } Prevention
- Expect Genius scraping to break periodically — update the plugin when it does
- Verify genius.com loads normally in a browser to rule out bot-blocking
- Order providers so scraping-based ones (Genius, Megalobiz) are tried after the stable API (LRCLib)
When it happens
Trigger: Genius changing their page structure (renaming the preloaded-state key or lyrics field); instrumented/lyrics-less pages (e.g. album or artist pages matched by mistake); pages where lyrics live behind interstitials; non-song results for the search query.
Common situations: Site redesigns by Genius breaking scrapers (recurring); region or bot checks serving a challenge page instead of the song page; tracks whose Genius page has no lyrics (instrumental entries without the placeholder marker).
Related errors
- Failed to extract lyrics from page.
- Expected an array, instead got ${typeof data}
- bad HTTPStatus(${response.statusText})
- bad HTTPStatus(${response.statusText})
AI-assisted analysis of pear-devs/pear-desktop@1e2aac5706 (2026-08-27).
Data as JSON: /api/errors/933fe4b5dc1c2ba6.
Report an issue: GitHub.