Skip to content

fix: use the ID3 getArtistInfo2 endpoint for artist info - #2309

Open
noctuum wants to merge 1 commit into
jeffvli:developmentfrom
noctuum:fix/subsonic-artist-info-id3-endpoint
Open

fix: use the ID3 getArtistInfo2 endpoint for artist info#2309
noctuum wants to merge 1 commit into
jeffvli:developmentfrom
noctuum:fix/subsonic-artist-info-id3-endpoint

Conversation

@noctuum

@noctuum noctuum commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Closes #2308

Problem

On the album artist detail page the "About" section and the "Related Artists" list belong to a completely different artist than the one the page is opened for. Albums, top songs and external links on the same page are correct.

Cause

Album artists are loaded through the ID3 endpoints (getArtists.view / getArtist.view), but artist info was requested through the non-ID3 getArtistInfo.view. The two endpoints resolve the id parameter in two different id namespaces, and the namespaces overlap numerically, so the id is valid in both and no error is raised.

Airsonic-Advanced resolves the id against media_file in getArtistInfo:

https://github.com/airsonic-advanced/airsonic-advanced/blob/68d11bfbfe051b0acaca2770c3c1f47f8d59201c/airsonic-main/src/main/java/org/airsonic/player/controller/SubsonicRESTController.java#L434-L440

and against the artist table in getArtistInfo2:

https://github.com/airsonic-advanced/airsonic-advanced/blob/68d11bfbfe051b0acaca2770c3c1f47f8d59201c/airsonic-main/src/main/java/org/airsonic/player/controller/SubsonicRESTController.java#L470-L476

Fix

getAlbumArtistInfo now calls getArtistInfo2.view in both the Subsonic and the Navidrome controller, and the response is typed by a new artistInfo2 schema.

Server Before After Basis
Airsonic / Airsonic-Advanced biography and similar artists of an unrelated artist correct artist tested
gonic no biography at all — getArtistInfo returns an empty response there correct artist expected, from reading the sources
Navidrome already correct — both endpoints are backed by the same handler unchanged expected, from reading the sources
Jellyfin not affected — separate code path, biography comes from Overview unchanged code inspection, not exercised

Only the Airsonic-Advanced row was verified on a running server. The other rows are inferred from the server sources, and I would appreciate a check by someone who runs those servers.

Screenshots (Airsonic-Advanced)

Before

before1 before2

After

after1 after2

Notes for review

  • No fallback to getArtistInfo is kept on purpose. That endpoint does not fail on an ID3 id, it returns a plausible-looking biography of the wrong artist, so a fallback would silently reintroduce the bug instead of guarding against it.
  • getArtistInfo2 requires Subsonic API 1.11.0. The client already advertises v=1.13.0, so no version bump is needed.
  • The new schema is written against actual server responses rather than copied from the old one: albumCount arrives as a number from Airsonic although the previous schema declared it a string, coverArt is missing on some entries, and gonic omits similarArtist entirely when the list is empty. These schemas are compile-time types only — the ts-rest client returns the raw body without parsing — so the mismatch surfaced as inaccurate types rather than a runtime error. String(artist.id) is needed because the shared id schema is number | string while RelatedArtist.id is string.

Testing

Tested on Airsonic-Advanced (REST API 1.15.0) only — that is the one server I have:

  • the same ID3 artist id returns an unrelated artist from getArtistInfo and the correct artist from getArtistInfo2;
  • running the app from source, the biography and the "Related Artists" list now both match the artist on the page;
  • pnpm typecheck and eslint src/ are clean.

Not tested on Navidrome, gonic, LMS, Ampache or Jellyfin.

Album artists are loaded through the ID3 endpoints, but artist info was
requested through the non-ID3 getArtistInfo. The two endpoints resolve the
id parameter in different id namespaces, which overlap numerically, so
servers that separate the namespaces returned the biography and similar
artists of an unrelated item that happened to share the numeric id.

Switch both the Subsonic and the Navidrome controller to getArtistInfo2 and
type the response with a new artistInfo2 schema matching what servers
actually return.
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
feishin Ready Ready Preview Jul 31, 2026 7:59pm

@kgarner7 kgarner7 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. This is an incorrect change.
getArtistInfo is specifically used because the spec notes that it fetches data from last.fm (or other providers). Just replacing this with getArtistInfo2 is not the right call. You could provide a toggle (although for Navidrome, there's no difference), but this alone is incorrect.

@noctuum

noctuum commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

@kgarner7 Could you point me at the part of the spec you have in mind? Reading the OpenSubsonic docs, both endpoints are last.fm-backed and were introduced in the same version:

  • getArtistInfo — "Returns artist info with biography, image URLs and similar artists, using data from last.fm." Since 1.11.0.
  • getArtistInfo2 — "Similar to getArtistInfo, but organizes music according to ID3 tags." Since 1.11.0.

The artistInfo2 response carries the same fields — biography, musicBrainzId and the three image URLs. As far as I can tell the only differences are the id namespace and the type of the similarArtist entries (Artist vs ArtistID3), not the data source or the provider.

What makes this a bug rather than a preference is the id. getAlbumArtistInfo is always called with an id that came from getArtists.view / getArtist.view, i.e. an ID3 id, and getArtistInfo resolves its id in the folder / media-file namespace instead. On Airsonic-Advanced that is mediaFileService.getMediaFile(id) versus artistDao.getArtist(id) in getArtistInfo2 (permalinks in the description). The two namespaces overlap numerically, so the lookup succeeds instead of failing and the server returns the last.fm data of an unrelated item — that is #2308.

So, concretely: which scenario do you have in mind where getArtistInfo returns correct data for an ID3 artist id? If Feishin had a folder-browsing path that produced folder ids, a toggle would make sense to me, but I could not find one — every call site of this endpoint gets its id from the ID3 endpoints.

If the concern is instead servers that implement getArtistInfo but not getArtistInfo2, I can add a fallback that only triggers on an error response. I left it out on purpose because getArtistInfo does not fail on an ID3 id, it answers with a plausible-looking biography of the wrong artist, so an unconditional fallback would quietly restore the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Artist biography and similar artists come from an unrelated artist on Subsonic servers

2 participants