grafana/k6 · error · ErrNotAuthenticated

failed to authenticate with k6 Cloud

Error message

failed to authenticate with k6 Cloud

What it means

After the isEnabled action succeeds (frame.go:1475), k6 asserts the result is a bool and errors with 'checking is %q enabled: unexpected type %T' otherwise. The state check returns a Go bool, so a non-bool (typically nil) indicates the action pipeline yielded an unexpected value: a race where the frame or execution context went away between resolution and result, or a browser-module bug. It is a defensive invariant error, not an application-level disabled state.

Source

Thrown at internal/cloudapi/httperr/httperr.go:15

// Package httperr contains HTTP-status-code error helpers shared by k6
// Cloud's API clients (cloudapi, internal/cloudapi/v6). It only covers the
// part of their CheckResponse-style functions that's genuinely identical
// across them - classifying 401/403 - everything else about decoding an
// error response body differs between API versions.
package httperr

import (
	"errors"
	"net/http"
)

var (
	// ErrNotAuthenticated maps HTTP 401.
	ErrNotAuthenticated = errors.New("failed to authenticate with k6 Cloud")
	// ErrNotAuthorized maps HTTP 403.
	ErrNotAuthorized = errors.New("not allowed to upload result to k6 Cloud")
)

// ClassifyStatus returns ErrNotAuthenticated for HTTP 401, ErrNotAuthorized
// for HTTP 403, and nil for any other status code.
func ClassifyStatus(statusCode int) error {
	switch statusCode {
	case http.StatusUnauthorized:
		return ErrNotAuthenticated
	case http.StatusForbidden:
		return ErrNotAuthorized
	default:
		return nil
	}
}

View on GitHub (pinned to 01ffac6f24)

Solutions

  1. Retry once after stabilizing the page (waitForLoadState/locator.waitFor) since the usual cause is a transient race.
  2. Avoid running state checks while navigation is in flight.
  3. Capture K6_DEBUG=true logs to identify the racing navigation.
  4. Report reproducible cases to grafana/k6 with script and versions.

Example fix

// before
const ok = await page.isEnabled('#submit');

// after
await page.waitForLoadState('domcontentloaded');
let ok;
try { ok = await page.isEnabled('#submit'); }
catch (e) {
  if (!String(e).includes('unexpected type')) throw e;
  ok = await page.isEnabled('#submit'); // single retry
}
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForLoadState('domcontentloaded');

Try / catch

try {
  return await page.isEnabled(sel);
} catch (e) {
  if (!String(e).includes('unexpected type')) throw e;
  await page.waitForLoadState('domcontentloaded');
  return await page.isEnabled(sel); // retry once past the race
}

Prevention

When it happens

Trigger: Navigation or iframe swap between selector resolution and result; nil result on a rare action error path; CDP session teardown races during the check; k6 browser-module regression in value conversion.

Common situations: CI flakiness around page transitions; SPA tests where checks coincide with rerenders; occurrences right after upgrading k6.

Understand the failure class

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/14850ced5d179e86. Report an issue: GitHub.