Skip to content

Errors

The ArtistHub API answers 200 OK for almost everything, including failures. GraphQL reports problems in the errors array of the response body. Always inspect errors before you trust data.

json
{
  "data": null,
  "errors": [
    {
      "extensions": { "code": "validation-failed", "path": "$.selectionSet.links" },
      "message": "field 'links' not found in type: 'query_root'"
    }
  ]
}

A partial success is possible: data may contain some fields while errors describes others that failed. Do not assume data === null on error.

Error codes

CodeWhere it comes fromMeaning
validation-failedGraphQL engineThe document references a field, argument, or type that does not exist for your role. Usually a missing token.
invalid-jwtGraphQL engineThe authorization token is malformed, truncated, or not signed by ArtistHub.
invalid-headersGraphQL engineThe authorization header is present but unparseable.
constraint-violationDatabaseA write violated a unique or foreign-key constraint — for example a domain + path pair that already exists.
permission-errorDatabaseThe write targeted a column your role is not allowed to set. See the per-page column allowlists.
not-supportedGraphQL engineThe operation is not available, such as sending GET or subscribing to a table without subscription support.
INTERNAL_SERVER_ERRORCustom resolverA hand-written resolver raised an error. The message is a plain-language description meant to be read.

Reading validation-failed

This one code covers two very different situations.

You are not authenticated. Without a valid token the request runs as anonymous, and the anonymous schema contains almost nothing. The engine correctly reports that links does not exist, because for that role it does not.

json
{ "extensions": { "code": "validation-failed", "path": "$.selectionSet.links" },
  "message": "field 'links' not found in type: 'query_root'" }

Your document is genuinely wrong. A misspelled field, a missing required argument, or a wrong variable type produces the same code with a different path.

The path tells you which. $.selectionSet.<field> on a field you know exists means check your header first.

Reading resolver errors

Custom resolvers (login, create_link, quick_create_link, claim_number, and the rest) surface INTERNAL_SERVER_ERROR with a human-readable message. These are the messages worth handling explicitly:

MessageRaised byCause
Invalid email or password.loginUnknown email or wrong password.
This account is disabled.loginAccount deactivated.
Authentication required.any authenticated resolverNo authorization header reached the resolver.
Invalid typecreate_linktype was not bio, release, or playlist.
Invalid spotify link for biocreate_linkA bio link needs an open.spotify.com/artist/... URL.
Invalid spotify link for releasecreate_linkA release link needs an album or track URL.
Invalid spotify link for playlistcreate_linkA playlist link needs a playlist URL.
Artist not found or user does not have access to the artistcreate_linkWrong artist_id, or your account is not attached to that artist.
Invalid domain or pathcreate_link, path_availabledomain failed hostname validation, or path was empty.
Path must be 3 at least characters.create_link, path_availablepath is shorter than three characters.
Artist does not have access to the domaincreate_linkA custom domain was used that is not assigned to this artist.
Path is not availablecreate_linkThat domain + path pair is already taken.
Autoplay track is only available for playlistscreate_linkautoplay_track was sent for a non-playlist link.
Autoplay track not found in the playlistcreate_linkThe track ID is not in the referenced Spotify playlist.
No access.link_statsThe link belongs to an artist you are not attached to.

Empty results are not errors

Because row-level permissions filter silently, requesting a resource you do not own returns an empty result, not an error.

json
{ "data": { "links_by_pk": null } }

means either "no such link" or "not yours" — the API deliberately does not distinguish them. If you expected a row, check that the ID is right and that the artist is attached to your account.

Retrying

SituationWhat to do
invalid-jwtRe-issue a token with login. Do not retry the same token.
validation-failedFix the document or the header. Retrying unchanged will fail again.
constraint-violationChange the conflicting value — a different path, for instance.
HTTP 5xx, or a resolver timeoutRetry with exponential backoff. Analytics fields are the most likely to be slow, since they call an external store.

Writes are not idempotent. Before retrying a create_link that timed out, query for the domain + path to check whether it actually succeeded.

ArtistHub developer documentation