HeyPuter/puter · error · HttpError

not_found

not_found

Error message

Username not found.

What it means

Returned by POST /login when a username is supplied but getByUsername resolves to null — no account exists with that exact username. It is a genuine not-found result from the user store (as opposed to the disguised system-user block at line 410 which reuses the same message).

Source

Thrown at src/backend/controllers/auth/AuthController.ts:399

            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 {
            user = await this.stores.user.getByEmail(email);
        }

        if (!user) {
            throw new HttpError(
                404,
                username ? 'Username not found.' : 'Email not found.',
                { legacyCode: 'not_found' },
            );
        }
        if (
            user.username === 'system' &&
            !(this.config as { allow_system_login?: boolean })
                .allow_system_login
        ) {
            throw new HttpError(
                404,
                username ? 'Username not found.' : 'Email not found.',
                { legacyCode: 'not_found' },
            );
        }
        if (user.suspended) {
            throw new HttpError(401, 'This account is suspended.', {

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Double-check the username spelling and case.
  2. If unsure, try logging in with the account's email instead.
  3. Register the account if it does not exist.

Example fix

// before
await fetch('/login', { method:'POST', body:JSON.stringify({ username: 'jsmith', password }) }); // no such user

// after: fall back to email lookup
await fetch('/login', { method:'POST', body:JSON.stringify({ email: 'jsmith@example.com', password }) });
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check existence only if enumeration is acceptable for your flow
// Otherwise just handle the 404 in the UI.

Try / catch

try { await login(username, password); }
catch (e) {
  if (e.code === 'not_found') { /* prompt the user to register or use email */ }
  else throw e;
}

Prevention

When it happens

Trigger: Logging in with a username that was never registered, was renamed, or was deleted; case-mismatch (usernames are looked up exactly).

Common situations: Typo in the username; account renamed; user confusion between username and email; deleted account.

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/e586fb45f1f058a8. Report an issue: GitHub.