Skip to content

fix(web): stop album tracks rendering a 12/31/69 date - #14579

Merged
dylanjeffers merged 1 commit into
mainfrom
fix/collection-date-epoch-fallback
Aug 28, 2026
Merged

fix(web): stop album tracks rendering a 12/31/69 date#14579
dylanjeffers merged 1 commit into
mainfrom
fix/collection-date-epoch-fallback

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

Problem

Tracks inside albums render their date as 12/31/69. Reported by Michael from support email (Slack), with three examples:

Root cause

The API is returning playlist_contents[].timestamp: 0 for exactly the rows that render as 1969 — a long-standing data condition, not new:

celestial  [(EvGyvNo, 0), (XBxbjPR, 1787595758), (rbNjPNY, 0), (qJp7xva, 0), ...]
UI          Prophecy 12/31/69 | Tommy 8/24/26 | Skullthor 12/31/69 | Jungle Punch 12/31/69

What changed is that the client stopped defending against it. The legacy collection lineup saga only assigned dateAdded when the timestamp was non-zero:

// packages/web/src/common/store/pages/collection/lineups/sagas.js (deleted)
if (times[i]) {
  metadata.dateAdded = dayjs.unix(times[i])
}

leaving it undefined on a zero so the downstream fallback fired:

date: metadata.dateAdded || metadata.created_at

#14178 ("Drop legacy lineup system") rewrote this tan-query-first and dropped the guard, always assigning dayjs.unix(time). dayjs.unix(0) is a truthy object, so the || created_at fallback in both formatMetadata and the mobile CollectionPage became dead code.

Albums only, as reported, because desktop/CollectionPage.tsx picks the column by type — isAlbum ? 'date' : 'addedDate' — and date is the one carrying the dead fallback.

Fix

Restore the intent at the source, so desktop and mobile both pick it up:

dateAdded: time ? dayjs.unix(time) : dayjs(t.created_at)

Note for review

onReorderTracks writes dateAdded.unix() back on-chain. With this change, reordering an affected album persists the track's created_at instead of 0 — a heal rather than a corruption, but it is a write side-effect of a display fix and worth a conscious ack. (The prior code path would have written the 0 straight back.)

No regression test: useCollectionPage has no existing test harness and pulls in the redux store, tan-query and the playback slice, so covering this one-line fallback would mean standing up substantial mocking.

Separate follow-up

Why some playlist_contents entries never get a time written is a server-side question this PR does not address. canonicalizePlaylistEntry in go-openaudio's ETL only emits time when the client sends one, with no block-time default — worth its own look.

Test plan

  • tsc --noEmit on packages/web — no errors in collection-page (remaining errors are pre-existing unbuilt-workspace noise)
  • Load the three album links above and confirm dates render as the track's creation date rather than 12/31/69
  • Confirm a playlist (not album) still shows its "Added" column correctly

🤖 Generated with Claude Code

Entries in playlist_contents whose added-timestamp was never written
carry time: 0. dayjs.unix(0) renders as 12/31/69, and because it is a
truthy object it also defeats the `dateAdded || created_at` fallback in
formatMetadata and the mobile CollectionPage, which was the guard that
used to cover this case.

The legacy collection lineup saga only assigned dateAdded when the
timestamp was non-zero, leaving it undefined so the fallback fired.
#14178 dropped that guard when it moved the page to tan-query, which is
what surfaced the dates. Restore the intent at the source so both
desktop and mobile pick it up.

Albums are where this is visible because the desktop table uses the
`date` column for albums and `addedDate` for playlists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 689e6dd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dylanjeffers
dylanjeffers merged commit b5970b0 into main Aug 28, 2026
17 checks passed
@dylanjeffers
dylanjeffers deleted the fix/collection-date-epoch-fallback branch August 28, 2026 19:16
dylanjeffers added a commit that referenced this pull request Sep 1, 2026
## Problem

`Web Lint & Stylelint` fails on main at 02ee302, which takes the whole
pipeline down with it — Web Build, Web Deploy, all three Desktop builds
and the **Production Release Gate** every one skipped. Nothing from that
run can ship.

```
18:1  error  `components/weekly-rotation` import should occur after import of `components/page/Page`   import/order
27:1  error  `components/weekly-rotation` import should occur after import of `components/tabs`        import/order
25:1  error  `components/weekly-rotation` import should occur after import of `components/nav/mobile/NavContext`  import/order
✖ 4 problems (3 errors, 1 warning)
```

## Cause

#14582 renamed `components/discover-weekly` →
`components/weekly-rotation` in place. `d` sorts before
`header`/`lineup`/`nav`/`page`/`tabs`; `w` sorts after all of them, so
the import line that was correctly placed under the old name is now out
of order under the new one. Three call sites were affected.

## Fix

Moved each `WeeklyRotationBanner` import to its new alphabetical
position. Import-only change — no runtime difference, and `--fix`
produces exactly this.

- `pages/feed-page/components/desktop/FeedPageContent.tsx`
- `pages/search-explore-page/components/desktop/SearchExplorePage.tsx`
- `pages/search-explore-page/components/mobile/SearchExplorePage.tsx`

## Test plan

- [x] All three files' `components/` import blocks verified in sorted
order
- [ ] CI lint green (the real check — this is the job that was failing)

## Note

This is currently what blocks the production web deploy. The Production
gate has five runs waiting back to Aug 24, including the 12/31/69
album-date fix (#14579); main HEAD couldn't join them because of this
lint failure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant