{"record":{"id":"5f878ede49ba7a74","repo":"jackwener/OpenCLI","slug":"empty-result-5f878e","errorCode":"EMPTY_RESULT","errorMessage":"No track found for: ${query}","messagePattern":"No track found for: (.+?)","errorType":"error_code","errorClass":"CliError","httpStatus":null,"severity":"warning","filePath":"clis/spotify/spotify.js","lineNumber":98,"sourceCode":"    const token = await getToken();\n    const res = await fetch(`https://api.spotify.com/v1${path}`, {\n        method,\n        headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },\n        body: body ? JSON.stringify(body) : undefined,\n    });\n    if (res.status === 204 || res.status === 202)\n        return null;\n    if (!res.ok) {\n        const err = await res.json().catch(() => ({}));\n        throw new CliError('API_ERROR', err?.error?.message || `Spotify API error ${res.status}`);\n    }\n    return res.json();\n}\nasync function findTrackUri(query) {\n    const data = await api('GET', `/search?q=${encodeURIComponent(query)}&type=track&limit=1`);\n    const track = getFirstSpotifyTrack(data);\n    if (!track)\n        throw new CliError('EMPTY_RESULT', `No track found for: ${query}`);\n    return track;\n}\nfunction openBrowser(url) {\n    const cmd = process.platform === 'win32' ? `start \"\" \"${url}\"` : process.platform === 'darwin' ? `open \"${url}\"` : `xdg-open \"${url}\"`;\n    exec(cmd);\n}\n// ── Commands ──────────────────────────────────────────────────────────────────\ncli({\n    site: 'spotify',\n    name: 'auth',\n    access: 'write',\n    description: 'Authenticate with Spotify (OAuth — run once)',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [],\n    columns: ['status'],\n    func: async () => {\n        assertSpotifyCredentialsConfigured(credentials, ENV_FILE);","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/spotify/spotify.js#L80-L116","documentation":"findTrackUri performs a Spotify search (type=track, limit=1) and throws EMPTY_RESULT when Spotify returns no usable track in the first result slot — i.e. getFirstSpotifyTrack(data) yields nothing. It distinguishes 'the API worked but found nothing' from API_ERROR so callers can treat it as an empty-search condition rather than a failure.","triggerScenarios":"Calling findTrackUri (via play-related commands) with a query string that matches zero tracks: nonsense strings, heavy misspellings, or a query containing only characters Spotify's search ignores.","commonSituations":"Users typing a track name with typos; searching regional/obscure tracks not in Spotify's catalog; scripts building queries from metadata (e.g. filename-derived) producing garbage queries; non-Latin scripts or special-character-only queries.","solutions":["Simplify the query: use 'artist track' without extra noise like '(official video)' or file extensions.","Check spelling and try the artist name plus partial title.","Verify the track exists by searching it in the Spotify app/web player.","In scripts, sanitize metadata-derived queries before passing them."],"exampleFix":"// before\nopencli spotify play \"track_unknown_xyz\"\n// after\nopencli spotify play \"Daft Punk One More Time\"","handlingStrategy":"fallback","validationCode":"const q = rawQuery.trim();\nif (!q || !/\\p{L}/u.test(q)) { console.error('Query has no usable search terms'); return null; }","typeGuard":null,"tryCatchPattern":"try {\n  const track = await findTrackUri(query);\n} catch (e) {\n  if (e.code === 'EMPTY_RESULT') {\n    const simplified = query.split(/\\s+/).slice(0, 3).join(' '); // retry with fewer terms\n    return findTrackUri(simplified);\n  }\n  throw e;\n}","preventionTips":["Strip noise tokens (file extensions, '(Official Video)', timestamps) from queries.","Prefer 'artist + title' over long descriptive strings.","Treat EMPTY_RESULT as a user-facing 'no match' message, not a crash."],"tags":["spotify","search","empty-result"],"backgroundTag":"empty-search-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}