grafana/k6 · error

parsing HTTP credentials: %w

Error message

parsing HTTP credentials: %w

What it means

browserContext.setHTTPCredentials(creds) exports its argument to common.Credentials, a struct of {username, password} strings. A non-object value or wrong-typed fields fail the export and are wrapped here. The API is deprecated (the mapping still exposes it for compatibility, marked with a staticcheck suppress) - prefer credentials on the HTTP layer instead.

Source

Thrown at internal/js/modules/k6/browser/browser/browser_context_mapping.go:106

			return promise(vu, func() (any, error) {
				return nil, bc.GrantPermissions(permissions, popts)
			}), nil
		},
		"setDefaultNavigationTimeout": bc.SetDefaultNavigationTimeout,
		"setDefaultTimeout":           bc.SetDefaultTimeout,
		"setGeolocation": func(geolocation sobek.Value) (*sobek.Promise, error) {
			gl, err := exportTo[common.Geolocation](vu.Runtime(), geolocation)
			if err != nil {
				return nil, fmt.Errorf("parsing geo location: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, bc.SetGeolocation(&gl)
			}), nil
		},
		"setHTTPCredentials": func(httpCredentials sobek.Value) (*sobek.Promise, error) {
			creds, err := exportTo[common.Credentials](rt, httpCredentials)
			if err != nil {
				return nil, fmt.Errorf("parsing HTTP credentials: %w", err)
			}
			return promise(vu, func() (any, error) {
				return nil, bc.SetHTTPCredentials(creds) //nolint:staticcheck
			}), nil
		},
		"setOffline": func(offline bool) *sobek.Promise {
			return promise(vu, func() (any, error) {
				return nil, bc.SetOffline(offline) //nolint:wrapcheck
			})
		},
		"waitForEvent": func(event string, optsOrPredicate sobek.Value) (*sobek.Promise, error) {
			rt := vu.Runtime()
			ctx := vu.Context()

			popts, err := parseWaitForEventOptions(rt, optsOrPredicate, bc.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing wait for event options: %w", err)
			}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Pass exactly { username: 'user', password: 'pass' } with string values
  2. Better: drop setHTTPCredentials (deprecated) and send an Authorization header or credentials in http requests directly
  3. Double-check any object spread merging credentials with other settings

Example fix

// before: joined string / wrong keys
await context.setHTTPCredentials('user:pass');
await context.setHTTPCredentials({ user: 'u', pass: 'p' });

// after: exact shape - or avoid the deprecated API via headers
await context.setHTTPCredentials({ username: 'user', password: 'pass' });
// preferred: page.goto basic-auth URL or Authorization header per request
Defensive patterns

Strategy: type-guard

Validate before calling

const creds = { username: String(process.env.USER_NAME ?? ''), password: String(process.env.PASSWORD ?? '') };
if (typeof creds.username !== 'string' || typeof creds.password !== 'string') {
  throw new TypeError('credentials must be { username: string, password: string }');
}
// better: skip the deprecated API and send an Authorization header per request

Type guard

function isCredentials(v) {
  return (
    typeof v === 'object' &&
    v !== null &&
    !Array.isArray(v) &&
    typeof v.username === 'string' &&
    typeof v.password === 'string'
  );
}

Try / catch

try {
  await context.setHTTPCredentials(creds);
} catch (e) {
  if (String(e).includes('parsing HTTP credentials')) {
    throw new Error('setHTTPCredentials expects { username, password } strings');
  }
  throw e;
}

Prevention

When it happens

Trigger: setHTTPCredentials('user:pass'); setHTTPCredentials({ user, pass }) (wrong key names); setHTTPCredentials({ username: 42 }); passing null/undefined where a partial object is expected to merge.

Common situations: Porting Playwright tests verbatim; not realizing the expected key names are username/password; scripted credential rotation passing joined strings.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/7b9ace47086121f0. Report an issue: GitHub.