{"record":{"id":"f79d676acef88039","repo":"gotify/server","slug":"application-does-not-exist","errorCode":null,"errorMessage":"application does not exist","messagePattern":"application does not exist","errorType":"http","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"api/message.go","lineNumber":191,"sourceCode":"//\t    description: Not Found\n//\t    schema:\n//\t        $ref: \"#/definitions/Error\"\nfunc (a *MessageAPI) GetMessagesWithApplication(ctx *gin.Context) {\n\twithID(ctx, \"id\", func(id uint) {\n\t\twithPaging(ctx, func(params *pagingParams) {\n\t\t\tapp, err := a.DB.GetApplicationByID(id)\n\t\t\tif success := successOrAbort(ctx, 500, err); !success {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif app != nil && app.UserID == auth.GetUserID(ctx) {\n\t\t\t\t// the +1 is used to check if there are more messages and will be removed on buildWithPaging\n\t\t\t\tmessages, err := a.DB.GetMessagesByApplicationSince(id, params.Limit+1, params.Since)\n\t\t\t\tif success := successOrAbort(ctx, 500, err); !success {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tctx.JSON(200, buildWithPaging(ctx, params, messages))\n\t\t\t} else {\n\t\t\t\tctx.AbortWithError(404, errors.New(\"application does not exist\"))\n\t\t\t}\n\t\t})\n\t})\n}\n\n// DeleteMessages delete all messages from a user.\n// swagger:operation DELETE /message message deleteMessages\n//\n// Delete all messages.\n//\n//\t---\n//\tproduces: [application/json]\n//\tsecurity: [clientTokenAuthorizationHeader: [], clientTokenHeader: [], clientTokenQuery: [], basicAuth: []]\n//\tresponses:\n//\t  200:\n//\t    description: Ok\n//\t  401:\n//\t    description: Unauthorized","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/api/message.go#L173-L209","documentation":"An HTTP 404 raised by the GET messages endpoint when the requested application ID either does not exist or exists but belongs to a different user. The handler first resolves the application; if the application is nil or its UserID does not match the authenticated user, it aborts with 'application does not exist' instead of listing messages. Note error 8 uses the near-identical but typo'd message 'application does not exists' on the DELETE path — both mean the same thing.","triggerScenarios":"GET /message?since=...&limit=... (the message listing endpoint) with an application ID that (1) does not exist, (2) was deleted, or (3) is owned by another user.","commonSituations":"Querying messages shortly after deleting the application; using an application ID from a different Gotify instance or environment; another user's application ID (404 is intentional to avoid leaking existence); token belongs to a different user than the application owner.","solutions":["Call GET /application with your token and confirm the application ID appears in the list before querying its messages.","Ensure the token used for the message query belongs to the same user who owns the application.","If the application was deleted, recreate it and use the new application ID.","Verify the request targets the correct server/instance (IDs are not globally unique across installations)."],"exampleFix":"// before\ncurl 'https://gotify.example/message?token=<tok>&app_id=999'   # app 999 not owned -> 404\n\n// after\n# 1. confirm ownership\napps=$(curl -s -H 'X-Gotify-Key: <user-token>' https://gotify.example/application)\n# 2. use a returned application id\ncurl -s -H 'X-Gotify-Key: <user-token>' 'https://gotify.example/message?token=<app-token>&since=0&limit=100'","handlingStrategy":"validation","validationCode":"// Verify the application exists and is yours before polling its messages\nconst apps = await fetch('/application', { headers: { 'X-Gotify-Key': userToken } }).then(r => r.json());\nif (!apps.some(a => a.id === appId)) {\n  throw new Error(`application ${appId} does not exist for this user`);\n}\n// safe to proceed: fetch(`/message?token=${appToken}&since=${since}&limit=${limit}`)","typeGuard":null,"tryCatchPattern":"const res = await fetch(`/message?token=${tok}&since=${since}`, { headers: { 'X-Gotify-Key': userToken } });\nif (res.status === 404) {\n  // re-list applications; if absent, resubscribe to a valid app instead of retrying the same ID\n  console.warn('application missing or not owned — refresh application list');\n}","preventionTips":["Resolve application IDs from GET /application each session rather than hard-coding them.","Use the application's own token for message queries and the owner's token for existence checks.","Handle 404 on long-running pollers: the app may have been deleted mid-poll; resubscribe to a new app ID.","IDs are per-instance — never reuse them across dev/staging/prod servers."],"tags":["http-404","gotify","rest-api","resource-not-found","message-polling"],"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"}