maotoumao/MusicFree · warning

panel.associateLrc.targetExpired

Error message

panel.associateLrc.targetExpired

What it means

When associating a lyric, the panel parses a unique key from the clipboard/input and looks it up in mediaCache. If no cached media entry exists for that key, the target media has 'expired' from cache, so association is aborted: a warning toast is shown and a sentinel Error('CLIPBOARD TIMEOUT') is thrown to signal the specific failure (so the generic fail toast at line 66 is suppressed).

Source

Thrown at src/components/panels/types/associateLrc.tsx:51

            height={vmax(30)}
            renderBody={() => (
                <>
                    <PanelHeader
                        title={t("panel.associateLrc.title")}
                        onCancel={hidePanel}
                        onOk={async () => {
                            const inputValue =
                                input ?? (await Clipboard.getString());
                            if (inputValue) {
                                try {
                                    const targetMedia = parseMediaUniqueKey(
                                        inputValue.trim(),
                                    );
                                    // 目标也要写进去
                                    const targetCache =
                                        mediaCache.getMediaCache(targetMedia);
                                    if (!targetCache) {
                                        Toast.warn(
                                            t("panel.associateLrc.targetExpired"),
                                        );
                                        // TODO: ERROR CODE
                                        throw new Error("CLIPBOARD TIMEOUT");
                                    }

                                    lyricManager.associateLyric(musicItem, {
                                        ...targetMedia,
                                        ...targetCache,
                                    });
                                    Toast.success(t("panel.associateLrc.toast.success"));
                                    hidePanel();
                                } catch (e: any) {
                                    if (e.message !== "CLIPBOARD TIMEOUT") {
                                        Toast.warn(t("panel.associateLrc.toast.fail"));
                                    }
                                    errorLog("关联歌词失败", e?.message);
                                }

View on GitHub (pinned to d118b18b3d)

Solutions

  1. Re-open the source media (play/search it) so mediaCache re-caches the entry, then retry the association.
  2. Paste the full media info instead of relying on a stale unique key from the clipboard.
  3. Type the key into the input field rather than falling back to Clipboard.getString() to avoid stale clipboard content.
  4. Developer: extend mediaCache TTL or persist cache entries across restarts.

Example fix

// before
const targetCache = mediaCache.getMediaCache(targetMedia);
if (!targetCache) {
    Toast.warn(t("panel.associateLrc.targetExpired"));
    throw new Error("CLIPBOARD TIMEOUT");
}
// after
const targetCache = mediaCache.getMediaCache(targetMedia);
if (!targetCache) {
    const refreshed = await mediaCache.addMusicToCache(targetMedia); // rehydrate
    if (!refreshed) {
        Toast.warn(t("panel.associateLrc.targetExpired"));
        throw new Error("CLIPBOARD TIMEOUT");
    }
}
Defensive patterns

Strategy: validation

Validate before calling

const targetMedia = parseMediaUniqueKey(inputValue.trim());
const targetCache = targetMedia ? mediaCache.getMediaCache(targetMedia) : undefined;
if (!targetCache) {
    // re-open/re-play the target media first, or abort before associating
    return;
}

Type guard

function hasCachedMedia(key: unknown): key is IMedia.MediaUniqueKey {
    return typeof key === 'string' && mediaCache.getMediaCache(parseMediaUniqueKey(key)) != null;
}

Try / catch

try {
    // association logic
} catch (e: any) {
    if (e?.message === "CLIPBOARD TIMEOUT") {
        // cache-miss path already toasted; do not double-toast
    } else {
        Toast.warn(t("panel.associateLrc.toast.fail"));
    }
}

Prevention

When it happens

Trigger: onOk in AssociateLrc (associateLrc.tsx:39-75) runs parseMediaUniqueKey(inputValue.trim()) and mediaCache.getMediaCache(targetMedia) returns undefined — i.e. the clipboard contains a media unique key whose cached entry was evicted or never existed (cache cleared, app restarted, or clipboard text is not a valid cached key).

Common situations: User copies a media key, clears app data/cache or restarts the app, then tries to associate lyrics; pasting arbitrary text that parses as a key but has no cache entry; mediaCache eviction after long sessions.

Related errors


AI-assisted analysis of maotoumao/MusicFree@d118b18b3d (2026-08-30). Data as JSON: /api/errors/acda795e58887a58. Report an issue: GitHub.