{"record":{"id":"182be68284dcd8c0","repo":"Budibase/budibase","slug":"no-user-id-provided-for-getting","errorCode":null,"errorMessage":"No user ID provided for getting","messagePattern":"No user ID provided for getting","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/api/controllers/public/users.ts","lineNumber":74,"sourceCode":"  ctx.body = await getUser(ctx, response._id)\n  if (removed) {\n    ctx.extra = { message: NO_ROLES_MSG }\n  }\n  return ctx\n}\n\nfunction isLoggedInUser(ctx: UserCtx, user: User) {\n  const loggedInId = ctx.user?._id\n  const globalUserId = dbCore.getGlobalIDFromUserMetadataID(loggedInId!)\n  // check both just incase\n  return globalUserId === user._id || loggedInId === user._id\n}\n\nfunction getUser(ctx: UserCtx, userId?: string) {\n  if (userId) {\n    ctx.params = { userId }\n  } else if (!ctx.params?.userId) {\n    throw new Error(\"No user ID provided for getting\")\n  }\n  return readGlobalUser(ctx)\n}\n\nexport async function search(ctx: UserCtx, next: Next) {\n  const { name } = ctx.request.body\n  const users = await allGlobalUsers(ctx)\n  ctx.body = stringSearch(users, name, \"email\")\n  await next()\n}\n\nexport async function create(ctx: UserCtx, next: Next) {\n  await createUpdateResponse(ctx)\n  await next()\n}\n\nexport async function read(ctx: UserCtx, next: Next) {\n  ctx.body = await readGlobalUser(ctx)","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/public/users.ts#L56-L92","documentation":"getUser throws this when neither an explicit userId argument nor ctx.params.userId is present, so there is no user identifier to pass to readGlobalUser.","triggerScenarios":"Calling the public users controller helpers (createUpdateResponse or user route wrappers) without a userId in params and without passing one to getUser.","commonSituations":"Route misconfiguration where :userId is missing from the path; calling the controller function programmatically without params; middleware stripping params.","solutions":["Ensure the route defines /:userId and Koa populates ctx.params.userId","Pass the userId explicitly when calling getUser programmatically","Check middleware isn't resetting ctx.params"],"exampleFix":"// before\nawait getUser(ctx) // ctx.params is empty\n// after\nawait getUser(ctx, userId) // or ensure ctx.params = { userId }","handlingStrategy":"validation","validationCode":"if (!userId && !ctx.params?.userId) throw new Error('A userId must be provided via params or argument')","typeGuard":"function hasUserId(ctx: { params?: { userId?: string } }, userId?: string): ctx is { params: { userId: string } } {\n  return typeof userId === 'string' || typeof ctx.params?.userId === 'string'\n}","tryCatchPattern":"try {\n  await getUser(ctx, userId)\n} catch (err) {\n  if (err.message === 'No user ID provided for getting') {\n    // recover by reading userId from the authenticated session or request body\n  }\n}","preventionTips":["Verify routes declare /:userId in the path","Pass userId explicitly when invoking controller helpers outside HTTP routing","Never have middleware delete or overwrite ctx.params"],"tags":["validation","users","api"],"backgroundTag":"missing-required-parameter","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}