HeyPuter/puter · error · HttpError
password_required
password_required
Error message
Password is required.
What it means
Returned by POST /login when 'password' is missing or not a string. This is the second validation check — the identifier was accepted but the password field is absent, null, or a non-string type. Its legacy code 'password_required' distinguishes it from the short-password 'Invalid password.' check that follows.
Source
Thrown at src/backend/controllers/auth/AuthController.ts:376
// coarser per-IP backstop stops an attacker from minting fresh
// fingerprint buckets by rotating client-controlled headers
// (User-Agent etc.). Same pattern on the other unauthenticated
// credential endpoints below.
rateLimit: [
{ scope: 'login', limit: 10, window: 15 * 60_000 },
{ scope: 'login-ip', limit: 50, window: 15 * 60_000, key: 'ip' },
],
})
async handleLogin(req: Request, res: Response): Promise<void> {
const { username, email, password } = req.body;
if (!username && !email) {
throw new HttpError(400, 'Username or email is required.', {
legacyCode: 'bad_request',
});
}
if (!password || typeof password !== 'string') {
throw new HttpError(400, 'Password is required.', {
legacyCode: 'password_required',
});
}
if (password.length < (this.config.min_pass_length || 6)) {
throw new HttpError(400, 'Invalid password.', {
legacyCode: 'bad_request',
});
}
// Look up user
let user;
if (username) {
if (typeof username !== 'string')
throw new HttpError(400, 'username must be a string.', {
legacyCode: 'bad_request',
});
user = await this.stores.user.getByUsername(username);
} else {View on GitHub (pinned to 908ec23eda)
Solutions
- Ensure a non-empty string 'password' is present in the JSON body.
- Validate client-side that the password field has a string value before submit.
- Check that the request body is parsed as JSON (Content-Type: application/json).
Example fix
// before
await fetch('/login', { method:'POST', body:JSON.stringify({ username }) });
// after
await fetch('/login', { method:'POST', body:JSON.stringify({ username, password: String(pwd) }) }); Defensive patterns
Strategy: validation
Validate before calling
if (typeof body.password !== 'string' || body.password.length === 0) {
throw new Error('Password is required.');
} Type guard
/** @returns {p is string} */
function isNonEmptyString(p) { return typeof p === 'string' && p.length > 0; } Prevention
- Coerce the password to a string before sending.
- Validate non-empty client-side to give a clearer message than the server's.
When it happens
Trigger: Submitting a login form before the password is entered; sending password as null, a number, or an object; a serialization bug that drops the field.
Common situations: Empty password field; client that hashes the password into a non-string field; test fixture omitting the field.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/753dfdd93c1a6e22.
Report an issue: GitHub.