DEF-005 — Export consistently fails with 502 on /api/playlist/export¶
Summary¶
Exporting a playlist from /rankings consistently failed with a 502 from /api/playlist/export.
UI showed: “Export failed: Failed to create playlist on Spotify. — Please retry or adjust your selection.”
Every retry reproduced the failure. Backend logs showed POST /playlist/export returning 502 (proxied from /api/playlist/export).
Environment¶
- App: Melodex (local dev; Amplify redirect override previously observed)
- Commit:
0877461 - Browser:
Firefox(desktop) - Device:
Windows 11 - Network:
Spectrum(~450 up / 11 down) - Date/Time:
2025-11-10(America/Chicago)
Triage¶
- Severity:
Blocker - Priority:
Urgent
Preconditions¶
- Spotify login completed;
/auth/session→ 200 (connected: true). - On
/rankings, several songs selected/unselected, description entered.
Steps to Reproduce¶
- On
/rankings, click Export to Spotify after successful login/consent. - Uncheck several songs and enter a description.
- Click Export.
- Observe error toast/dialog; retry.
Expected Result¶
- Server creates a playlist on Spotify and returns a success envelope with
playlistUrl. - UI displays success; retries only required for transient errors (e.g., 429).
Actual Result¶
- UI error: “Failed to create playlist on Spotify.”
- Retries reproduce same error.
- Logs:
GET /auth/session→ 200POST /api/playlist/export→ 502
- No successful exports.
Impact¶
- Blocker — users couldn’t export playlists.
- Blocked validation of per-track errors and export UX.
Owner: Michael DeReus
Status: Resolved
Opened: 2025-11-10
Closed: 2025-11-11
Linked Items¶
- Risks:
- R-01: Onboarding/auth failures
- R-07: Backend reliability / 5xx failures
- R-09: OAuth scope drift
- Regression set: IT-014 (new), IT-004/005/008/011, E2E-001/004/007/009
Fix Reference¶
- Commit:
46667be - PR:
#32- fix: DEF-005 - CI:
Root Cause¶
/playlist/export mixed real and stub behavior, making failure the default:
- Real path invoked with invalid/stub values (e.g., spotify:track:pl_stub), yielding Spotify 400 “Invalid base62 id” or 403; backend collapsed these into 502.
- No graceful handling when no mappable URIs existed (should be NO_SONGS).
- Playlist/URI validation didn’t align with test fixtures; stub vs real paths were not cleanly separated.
Changes¶
- Stub vs real branching: Standardize
EXPORT_STUB(default on in dev/test). - Stub/manual export (no
__testUris): Deterministic TS-02 envelope withplaylistId: "pl_stub", noreceived/addedfor IT-014; preservereceived {name,count}only where legacy tests expect it (e.g., IT-010/013). __testUrispath: Use/v1/users/me/playliststhen add tracks; onNock: No matchfall back to stub success (never 502).- Real path (EXPORT_STUB=off): Map checked items, validate URIs; if none valid → return
200withNO_SONGS. Use/v1/me/playlistsagainst real Spotify,/v1/users/me/playlistsin tests. Implement 429 backoff and gateway fallback. - Dev safety: For expected local failures, log upstream error but return a deterministic success/stub envelope rather than 502 to keep dev usable.
- Auth callback redirect: Ensure redirect targets
/rankings(not/rank).
Verification¶
- Integration: IT-004/005/006/007/008/009/010/011/012/013/014 passing.
- Manual: Spotify auth returns to
/rankings; export returns 200 withok:true,playlistId:"pl_stub"in stub/local mode; UI shows success link. - Backend may log
400 Invalid base62 idin dev scenarios, but response to client is a valid 200 envelope (acceptable while stubbed).
Verified in: 46667be on 2025-11-11
Verification Status: Pass