{"record":{"id":"d8f3d0f5d2c76804","repo":"gotify/server","slug":"invalid-id","errorCode":null,"errorMessage":"invalid id","messagePattern":"invalid id","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"api/internalutil.go","lineNumber":15,"sourceCode":"package api\n\nimport (\n\t\"errors\"\n\t\"math/bits\"\n\t\"strconv\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc withID(ctx *gin.Context, name string, f func(id uint)) {\n\tif id, err := strconv.ParseUint(ctx.Param(name), 10, bits.UintSize); err == nil {\n\t\tf(uint(id))\n\t} else {\n\t\tctx.AbortWithError(400, errors.New(\"invalid id\"))\n\t}\n}\n","sourceCodeStart":1,"sourceCodeEnd":18,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/api/internalutil.go#L1-L18","documentation":"withID is a Gin route-handler wrapper that parses a numeric path parameter via strconv.ParseUint and only invokes the wrapped handler on success. If the parameter is not a valid unsigned integer, it aborts with HTTP 400 and 'invalid id'. It guards all application/client mutation and read routes (DeleteApplication, UpdateApplication, UpdateApplicationSecurity, UploadApplicationImage, RemoveApplicationImage, UpdateClient, message routes, etc.).","triggerScenarios":"Any withID-wrapped route called with a path parameter that fails ParseUint: a non-numeric value (e.g. /application/abc), a negative number (e.g. /client/-1 — minus sign is rejected for unsigned), a value exceeding uint range on 32-bit platforms, an empty segment (e.g. /application//update), or an ID with whitespace or URL-encoded characters.","commonSituations":"String template variables left unfilled ('${id}' literally in the URL); client-side code interpolating undefined/null (renders 'undefined' or empty); truncated URLs from bad redirect logic; assuming string slugs/UUIDs work instead of the numeric IDs this API expects; 32-bit builds overflowing large IDs.","solutions":["Send the numeric unsigned ID in the path: /application/42, not /application/abc or /application/-1.","Log and inspect the exact request URL — the offending segment is the path parameter named by the route.","Fix client-side interpolation so the ID variable is defined and numeric before building the URL.","If you only have a token or name, look up the numeric ID first via the corresponding list endpoint.","On 32-bit deployments, confirm IDs fit in 32 bits or run a 64-bit build."],"exampleFix":"// before\nfetch(`/application/${id}/update`, { method: 'PUT' }) // id === undefined -> /application/undefined/update -> 400 'invalid id'\n\n// after\nif (!Number.isInteger(id) || id < 0) throw new Error('application id must be a non-negative integer');\nfetch(`/application/${id}/update`, { method: 'PUT' })","handlingStrategy":"validation","validationCode":"// Validate the path ID before building any withID-wrapped URL\nfunction assertPathId(name, value) {\n  const n = Number(value);\n  if (!Number.isInteger(n) || n < 0 || !Number.isSafeInteger(n)) {\n    throw new TypeError(`${name} must be a non-negative integer, got: ${JSON.stringify(value)}`);\n  }\n  return n;\n}\nconst id = assertPathId('application id', rawId); // throws early instead of HTTP 400","typeGuard":"function isUintId(v) {\n  return typeof v === 'number' ? Number.isInteger(v) && v >= 0\n    : typeof v === 'string' && /^\\d+$/.test(v);\n}","tryCatchPattern":"const res = await fetch(`/application/${id}/update`, { method: 'PUT', body });\nif (res.status === 400) {\n  const body = await res.text();\n  if (body.includes('invalid id')) throw new Error(`path id '${id}' is not a valid unsigned integer`);\n}","preventionTips":["Interpolate defined numeric variables into URL templates; guard against undefined/null becoming 'undefined'.","Never send negative or decimal numbers — ParseUint rejects them.","Remember the API expects numeric IDs only; slugs/UUIDs/name strings will always 400.","On 32-bit hosts, keep IDs within 32-bit unsigned range."],"tags":["http-400","input-validation","path-parameter","gotify","rest-api"],"backgroundTag":"invalid-path-parameter","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"}