ERROR album: HTTP 500 on the first real index. Not the URL and not the key:
the indexer calls artist first and album second, and the failure was on the
second, so connectivity and auth were already proven.
The cause is which album endpoint was used. Lidarr has two, and they are not
equally safe.
GET /api/v1/album?artistId=N maps straight from the album service with no
hydration:
The mapper it reaches then dereferences model.Images.JsonClone() and model.SecondaryTypes.Select(...) with no null check, follows model.Artist?.Value where only the first link is guarded, and picks the
release with SingleOrDefault(x => x.Monitored) -- which throws outright when
an album has two monitored releases. Any of those is a 500 that aborts the
entire index.
GET /api/v1/album with no filter builds its own artist and release lookups
first and skips what it cannot hydrate:
if (!artists.TryGetValue(album.ArtistMetadataId, out var albumArtist))
Change
Fetch albums once from the unfiltered endpoint and group by artistId
locally. It is the defensive path, and it costs N fewer requests.
Tracks and files have no unfiltered endpoint -- Lidarr rejects a call with no
filter at all -- so they stay per artist. A failure on one artist now skips
that artist instead of ending the run.
A skipped artist is counted into the store, and the coverage report leads
with it. A missing artist makes their played music look unplayed, which is
exactly the error that costs music in stage four, so an incomplete index must
never be culled against. Silently continuing would have been worse than
failing.
Errors now carry the request URL and whatever the server put in the body.
"album: HTTP 500" pointed at the URL and the credentials, neither of which
was at fault; that should not have needed a source dive to work out.
Testing
44 tests, green locally and in docker build --target test. New ones cover the
unfiltered album call, an artist Lidarr refuses to serve leaving the rest of
the index intact, the skip being recorded, and the error message carrying the
URL and the server's own text.
## Problem
`ERROR album: HTTP 500` on the first real index. Not the URL and not the key:
the indexer calls `artist` first and `album` second, and the failure was on the
second, so connectivity and auth were already proven.
The cause is which album endpoint was used. Lidarr has two, and they are not
equally safe.
`GET /api/v1/album?artistId=N` maps straight from the album service with no
hydration:
return MapToResource(_albumService.GetAlbumsByArtist(artistId.Value), false);
The mapper it reaches then dereferences `model.Images.JsonClone()` and
`model.SecondaryTypes.Select(...)` with no null check, follows
`model.Artist?.Value` where only the first link is guarded, and picks the
release with `SingleOrDefault(x => x.Monitored)` -- which throws outright when
an album has two monitored releases. Any of those is a 500 that aborts the
entire index.
`GET /api/v1/album` with no filter builds its own artist and release lookups
first and skips what it cannot hydrate:
if (!artists.TryGetValue(album.ArtistMetadataId, out var albumArtist))
## Change
- Fetch albums once from the unfiltered endpoint and group by `artistId`
locally. It is the defensive path, and it costs N fewer requests.
- Tracks and files have no unfiltered endpoint -- Lidarr rejects a call with no
filter at all -- so they stay per artist. A failure on one artist now skips
that artist instead of ending the run.
- A skipped artist is counted into the store, and the coverage report leads
with it. A missing artist makes their played music look unplayed, which is
exactly the error that costs music in stage four, so an incomplete index must
never be culled against. Silently continuing would have been worse than
failing.
- Errors now carry the request URL and whatever the server put in the body.
"album: HTTP 500" pointed at the URL and the credentials, neither of which
was at fault; that should not have needed a source dive to work out.
## Testing
44 tests, green locally and in `docker build --target test`. New ones cover the
unfiltered album call, an artist Lidarr refuses to serve leaving the rest of
the index intact, the skip being recorded, and the error message carrying the
URL and the server's own text.
Indexing fetched albums one artist at a time, and `GET /api/v1/album?artistId=`
is Lidarr's unguarded path. It maps straight from the album service with no
hydration: the mapper then dereferences model.Images and model.SecondaryTypes
without a null check, follows model.Artist?.Value where only the first link is
guarded, and selects the monitored release with SingleOrDefault, which throws
outright when an album has two of them. Any of those is a 500 that aborts the
whole index.
The unfiltered `GET /api/v1/album` builds its own artist and release lookups and
skips an album whose metadata is missing rather than dereferencing it. Use that
instead, once, and group by artistId locally. It is the defensive path and it
costs N fewer requests.
Tracks and files have no unfiltered endpoint -- Lidarr rejects a call with no
filter at all -- so those stay per artist. A failure on one artist now skips
that artist rather than ending the run, but the count is recorded in the store
and the coverage report leads with it: a missing artist makes their played music
look unplayed, which is precisely the error that costs music later, so an
incomplete index must not be culled against.
Errors now carry the request URL and whatever the server put in the body. The
original report of this failure was "album: HTTP 500", which points at the URL
and the credentials -- neither of which was at fault.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
ERROR album: HTTP 500on the first real index. Not the URL and not the key:the indexer calls
artistfirst andalbumsecond, and the failure was on thesecond, so connectivity and auth were already proven.
The cause is which album endpoint was used. Lidarr has two, and they are not
equally safe.
GET /api/v1/album?artistId=Nmaps straight from the album service with nohydration:
The mapper it reaches then dereferences
model.Images.JsonClone()andmodel.SecondaryTypes.Select(...)with no null check, followsmodel.Artist?.Valuewhere only the first link is guarded, and picks therelease with
SingleOrDefault(x => x.Monitored)-- which throws outright whenan album has two monitored releases. Any of those is a 500 that aborts the
entire index.
GET /api/v1/albumwith no filter builds its own artist and release lookupsfirst and skips what it cannot hydrate:
Change
artistIdlocally. It is the defensive path, and it costs N fewer requests.
filter at all -- so they stay per artist. A failure on one artist now skips
that artist instead of ending the run.
with it. A missing artist makes their played music look unplayed, which is
exactly the error that costs music in stage four, so an incomplete index must
never be culled against. Silently continuing would have been worse than
failing.
"album: HTTP 500" pointed at the URL and the credentials, neither of which
was at fault; that should not have needed a source dive to work out.
Testing
44 tests, green locally and in
docker build --target test. New ones cover theunfiltered album call, an artist Lidarr refuses to serve leaving the rest of
the index intact, the skip being recorded, and the error message carrying the
URL and the server's own text.