honojs/hono · error · Error

basic auth middleware requires options for "username and pas

Error message

basic auth middleware requires options for "username and password" or "verifyUser"

What it means

This error is thrown synchronously by Hono's basicAuth() middleware factory at creation time when the options object contains neither a username/password pair nor a verifyUser function. The middleware needs at least one way to decide which credentials are valid, so it refuses to build the handler. It is a configuration/programming error, not a runtime request error.

Source

Thrown at src/middleware/basic-auth/index.ts:88

 *     username: 'hono',
 *     password: 'ahotproject',
 *     onAuthSuccess: (c, username) => {
 *       c.set('user', { name: username, role: 'admin' })
 *       console.log(`User ${username} authenticated`)
 *     },
 *   })
 * )
 * ```
 */
export const basicAuth = (
  options: BasicAuthOptions,
  ...users: { username: string; password: string }[]
): MiddlewareHandler => {
  const usernamePasswordInOptions = 'username' in options && 'password' in options
  const verifyUserInOptions = 'verifyUser' in options

  if (!(usernamePasswordInOptions || verifyUserInOptions)) {
    throw new Error(
      'basic auth middleware requires options for "username and password" or "verifyUser"'
    )
  }

  if (!options.realm) {
    options.realm = 'Secure Area'
  }

  if (!options.invalidUserMessage) {
    options.invalidUserMessage = 'Unauthorized'
  }

  if (usernamePasswordInOptions) {
    users.unshift({ username: options.username, password: options.password })
  }

  return async function basicAuth(ctx, next) {
    const requestUser = auth(ctx.req.raw)

View on GitHub (pinned to e2740d5a1b)

Solutions

  1. Add a static credential pair: basicAuth({ username: 'admin', password: 'secret' })
  2. Or supply an async verifier: basicAuth({ verifyUser: async (user, pass) => ... })
  3. If you meant multiple users, keep username/password set or implement verifyUser that checks a user store
  4. Double-check option spelling — both 'username' AND 'password' must be present for the static path

Example fix

// before
app.use('/admin/*', basicAuth({ realm: 'Admin' }))

// after
app.use('/admin/*', basicAuth({
  realm: 'Admin',
  username: 'admin',
  password: process.env.ADMIN_PASSWORD!,
}))
Defensive patterns

Strategy: validation

Validate before calling

import { basicAuth } from 'hono/basic-auth'
const isValidBasicAuthOptions = (o: Record<string, unknown>): boolean =>
  (('username' in o && 'password' in o) || 'verifyUser' in o)

if (!isValidBasicAuthOptions(options)) {
  throw new Error('basicAuth needs username+password or verifyUser')
}
const middleware = basicAuth(options as any)

Type guard

type BasicAuthUserPass = { username: string; password: string }
type BasicAuthVerify = { verifyUser: (u: string, p: string, c: Context) => boolean | Promise<boolean> }
type ValidBasicAuthOptions = BasicAuthUserPass | BasicAuthVerify
const hasValidBasicAuth = (o: Partial<BasicAuthUserPass & BasicAuthVerify>): o is ValidBasicAuthOptions =>
  (o.username !== undefined && o.password !== undefined) || typeof o.verifyUser === 'function'

Prevention

When it happens

Trigger: Calling basicAuth({ realm: 'Secure' }) with no auth criteria; passing only username without password (e.g. basicAuth({ username: 'admin' })); passing only password; misspelling options like basicAuth({ users: [...] }) without verifyUser; passing an empty options object basicAuth({}).

Common situations: Typos in option names (user instead of username), copying an example that relies on verifyUser but forgetting to include the function, refactoring from a single user to a user list and dropping the credentials, or conditionally building options where both branches omit the auth fields.

Related errors


AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28). Data as JSON: /api/errors/fa1d7a5236634fbe. Report an issue: GitHub.