grafana/k6 · error
received empty projects page with next link
Error message
received empty projects page with next link
What it means
Thrown by the k6 Cloud v6 API client's project-list pagination loop when a page returned by ProjectsList contains a non-empty nextLink but an empty value array. The client treats this as a violated pagination contract: skipping would silently drop projects and following the link blindly could loop forever, so it aborts the whole listing.
Source
Thrown at internal/cloudapi/v6/api.go:76
res, err := c.listProjectsPage(ctx, skip, pageSize)
if err != nil {
return nil, err
}
for _, project := range res.Value {
projects = append(projects, Project{
ID: project.Id,
Name: project.Name,
IsDefault: project.IsDefault,
})
}
if res.NextLink == nil || *res.NextLink == "" {
return projects, nil
}
if len(res.Value) == 0 {
return nil, errors.New("received empty projects page with next link")
}
skip += pageSize
}
}
func (c *Client) listProjectsPage(
ctx context.Context, skip, top int32,
) (*k6cloud.ProjectListResponse, error) {
res, hr, err := c.apiClient.ProjectsAPI.
ProjectsList(c.authCtx(ctx)).
XStackId(c.stackID).
Skip(skip).
Top(top).
Execute()
defer closeResponse(hr, &err)
if err := CheckResponse(hr, err); err != nil {
return nil, errView on GitHub (pinned to 93accf6570)
Solutions
- Retry the same command once or twice; most occurrences are transient server-side
- Verify the stack URL/slug is correct so you are hitting the expected API endpoint
- Upgrade k6 to the latest release in case the vendored cloud API client is out of sync with the API
- Re-run with K6_LOG_LEVEL=debug (and HTTP debugging enabled) to capture the raw page response and report it to Grafana support
Example fix
// before: single-shot call that surfaces the pagination anomaly directly
projects, err := client.ListProjects(ctx)
if err != nil {
return err // "received empty projects page with next link"
}
// after: retry the listing a few times with backoff
var projects []k6cloud.Project
for attempt := 0; attempt < 3; attempt++ {
projects, err = client.ListProjects(ctx)
if err == nil {
break
}
time.Sleep(time.Duration(attempt+1) * time.Second)
} Defensive patterns
Strategy: retry
Try / catch
var projects []k6cloud.Project
err := backoff.Retry(func() error {
var e error
projects, e = client.ListProjects(ctx)
if e != nil && strings.Contains(e.Error(), "empty projects page") {
return e // transient pagination anomaly, retry
}
return backoff.Permanent(e)
}, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 3)) Prevention
- Pin a recent k6 version so the vendored cloud API client tracks the deployed API
- In smoke tests against the cloud API, exercise ListProjects once before long runs to fail early
- Enable debug HTTP logging (K6_LOG_LEVEL=debug) when first integrating to capture anomalous pages
When it happens
Trigger: Calling Client.ListProjects (project discovery during `k6 cloud login` or project resolution) where the server responds 200 OK with Value=[] while NextLink is set. Only the server/proxy response shape triggers it; client-side config cannot.
Common situations: A Grafana Cloud API pagination glitch, an intermediate proxy or gateway mangling the response body, or a version skew between the vendored k6-cloud-openapi-client-go and the live API. Rare; usually transient.
Related errors
- received empty load tests page with next link
- unexpected nil response from CreateOrFindLoadTest
- load test not found
- stack URL is required to validate token
- could not create the cloud test run: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/87065c34cc9e7610.
Report an issue: GitHub.