Budibase/budibase · error
Cannot reset password.
Error message
Cannot reset password.
What it means
The worker's resetUpdate endpoint wraps the entire password-reset flow in a try/catch and, for security, re-throws any underlying failure as a 400 with either the original message or the generic fallback 'Cannot reset password.'. The real cause (invalid/expired reset code, user not found, CouchDB error) is intentionally hidden so attackers cannot probe which reset tokens are valid. Whenever you see this message it means an exception escaped the reset handler, not that the new password itself was rejected.
Source
Thrown at packages/worker/src/api/controllers/global/auth.ts:272
}
}
/**
* Perform the user password update if the provided reset code is valid.
*/
export const resetUpdate = async (
ctx: Ctx<PasswordResetUpdateRequest, PasswordResetUpdateResponse>
) => {
const { resetCode, password } = ctx.request.body
try {
await authSdk.resetUpdate(resetCode, password)
ctx.body = {
message: "password reset successfully.",
}
} catch (err: any) {
console.warn(err)
// hide any details of the error for security
ctx.throw(400, err.message || "Cannot reset password.")
}
}
// DATASOURCE
export const datasourcePreAuth = async (
ctx: UserCtx<void, void>,
next: Next
) => {
const provider = ctx.params.provider
const returnPath =
typeof ctx.query.returnPath === "string" ? ctx.query.returnPath : undefined
const { middleware } = require(`@budibase/backend-core`)
const handler = middleware.datasource[provider]
if (!handler) {
ctx.throw(400, "Unsupported datasource provider")
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Request a fresh password-reset email and use the new link promptly (codes are single-use and expire).
- Check worker logs for the console.warn(err) output to see the underlying cause that was hidden from the client.
- Verify Redis/invite cache connectivity on the worker; restart it if the cache is unreachable.
- For multi-tenant deployments, confirm the request includes the correct tenantId so the code is looked up in the right tenant DB.
Example fix
// before: reusing an expired link fails with 'Cannot reset password.'
fetch(`/api/global/auth/reset?code=${oldCode}`, { ... })
// after: fetch a new code, then reset
const { code } = await requestReset(email)
await resetPassword({ code, password: newPassword }) Defensive patterns
Strategy: try-catch
Validate before calling
// client-side pre-check before calling reset
if (!code || !newPassword || newPassword.length < 8) {
throw new Error("Reset code and a valid new password are required")
} Try / catch
try {
await api.resetPassword({ code, password })
} catch (e) {
// 400 hides the real cause for security; treat as 'request a new reset email'
notifyUser("Reset failed or link expired — please request a new reset email")
} Prevention
- Use reset links immediately; codes are single-use and expire
- Always send the correct tenantId in multi-tenant setups
- Monitor worker logs for the underlying console.warn(err) cause
When it happens
Trigger: POST to the worker password-reset endpoint (resetUpdate) where: the reset code stored in the invite cache is missing, expired or for a different tenant; cache.invite.updateCode throws; the target user cannot be found; or any other exception occurs inside the handler.
Common situations: User clicks an emailed reset link after the code expired or was already consumed; Redis/CouchDB outage while resolving the reset code; multi-tenant setups where the tenantId is not supplied so the code is looked up in the wrong tenant; stale email links pointing at a different environment.
Related errors
- CouchDB password not set
- Invalid object store key: path traversal is not allowed.
- Access denied to object store bucket.${err}
- Only HTTP(S) URLs are allowed.
- URL must not include credentials.
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/aea70ef86c7b1b66.
Report an issue: GitHub.