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

  1. Ensure a non-empty string 'password' is present in the JSON body.
  2. Validate client-side that the password field has a string value before submit.
  3. 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

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.