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
- Retry once after stabilizing the page (waitForLoadState/locator.waitFor) since the usual cause is a transient race.
- Avoid running state checks while navigation is in flight.
- Capture K6_DEBUG=true logs to identify the racing navigation.
- 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
- Sequence state checks after load-state waits, not during transitions.
- Avoid racing checks with form submissions that navigate.
- Report persistent occurrences upstream with a repro.
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- ${name} constructor must be called with new
- an error occurred communicating with the provisioning API
- Error while parsing selector `${selector}` - selector cannot
- "level" attribute must be compared to a number
- "name" attribute must be a string or a regular expression
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/14850ced5d179e86.
Report an issue: GitHub.