{"record":{"id":"a89bf23662da1336","repo":"gotify/server","slug":"client-not-found","errorCode":null,"errorMessage":"client not found","messagePattern":"client not found","errorType":"http","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"api/client.go","lineNumber":314,"sourceCode":"//\t        $ref: \"#/definitions/Error\"\n//\t  404:\n//\t    description: Not Found\n//\t    schema:\n//\t        $ref: \"#/definitions/Error\"\nfunc (a *ClientAPI) ElevateClient(ctx *gin.Context) {\n\twithID(ctx, \"id\", func(id uint) {\n\t\tvar params model.ElevateRequest\n\t\tif err := ctx.Bind(&params); err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tclient, err := a.DB.GetClientByID(id)\n\t\tif err != nil {\n\t\t\tctx.AbortWithError(500, err)\n\t\t\treturn\n\t\t}\n\t\tif client == nil || client.UserID != auth.GetUserID(ctx) {\n\t\t\tctx.AbortWithError(404, errors.New(\"client not found\"))\n\t\t\treturn\n\t\t}\n\n\t\televatedUntil := time.Now().Add(time.Duration(params.DurationSeconds) * time.Second)\n\t\tif err := a.DB.UpdateClientElevatedUntil(client.ID, &elevatedUntil); err != nil {\n\t\t\tctx.AbortWithError(500, err)\n\t\t\treturn\n\t\t}\n\n\t\tctx.Status(204)\n\t})\n}\n","sourceCodeStart":296,"sourceCodeEnd":327,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/api/client.go#L296-L327","documentation":"This is an HTTP 404 raised in the client privilege-elevation handler when GetClientByID returns no client for the path ID, or when the client exists but belongs to a different user than the authenticated one. The library deliberately collapses 'missing' and 'not yours' into a single 404 to avoid leaking resource existence to other users. It is not a database failure — 500 is used separately for DB errors.","triggerScenarios":"Calling the client elevation endpoint (e.g. POST /client/{id}/elevate) with: (1) a client ID that does not exist, (2) a client ID that was deleted, or (3) a client ID owned by another authenticated user (client.UserID != auth.GetUserID).","commonSituations":"Stale IDs cached in scripts or mobile apps after the client was revoked; copy-pasting a client ID from another account/environment; testing with an admin token but a client from a normal user account; ID confusion between application IDs and client IDs.","solutions":["List your clients (GET /client) with the same token and confirm the ID exists in that response before elevating it.","Verify you are authenticating as the user who owns the client — a valid ID from another user also returns 404.","Check for typos or truncated IDs in the URL path; the ID must be the numeric client ID, not a token or name.","If the client was deleted, create a new client and use its ID."],"exampleFix":"// before\ncurl -X POST https://gotify.example/client/999/elevate -H 'X-Gotify-Key: WRONG_USER_TOKEN'\n\n// after\n# fetch clients with the owning user's token, then use a returned id\ncurl -H 'X-Gotify-Key: <user-token>' https://gotify.example/client\n# -> [{\"id\": 42, ...}]\ncurl -X POST -H 'X-Gotify-Key: <user-token>' https://gotify.example/client/42/elevate","handlingStrategy":"validation","validationCode":"// Client-side pre-check before calling the elevate endpoint\nconst clients = await fetch('/client', { headers: { 'X-Gotify-Key': token } }).then(r => r.json());\nconst mine = clients.find(c => c.id === clientId);\nif (!mine) throw new Error(`client ${clientId} not found for this user — refusing to call elevate`);","typeGuard":null,"tryCatchPattern":"// The error surfaces as HTTP 404, not an exception\nconst res = await fetch(`/client/${clientId}/elevate`, { method: 'POST', headers: { 'X-Gotify-Key': token } });\nif (res.status === 404) {\n  // missing OR not owned — refresh client list and re-check ownership\n  console.warn('client not found: verify ID and that it belongs to your user');\n}","preventionTips":["Always fetch IDs from GET /client with the same token you will elevate with.","Remember 404 also means 'not owned by you' — never retry blindly with another user's token.","Clear cached client IDs after revoking or recreating clients.","Distinguish client IDs from application IDs; they are separate ID spaces."],"tags":["http-404","authorization","gotify","rest-api","client-management"],"backgroundTag":"http-404-resource-not-found","analyzedSha":"14bfc256276775c425f988d621dccfe705de18ac","analyzedAt":"2026-09-05T12:52:36.781Z","contentChangedAt":"2026-09-05T12:52:36.781Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}