grafana/k6 · error
received empty load tests page with next link
Error message
received empty load tests page with next link
What it means
Thrown by the k6 Cloud v6 API client's load-test-list pagination loop when a page returned by ProjectsLoadTestsRetrieve has a non-empty nextLink but an empty value array. Like the projects variant, it guards against a server response that would otherwise cause either an infinite pagination loop or silently incomplete results.
Source
Thrown at internal/cloudapi/v6/api.go:131
return nil, err
}
for _, test := range res.Value {
tests = append(tests, LoadTest{
ID: test.Id,
ProjectID: test.ProjectId,
Name: test.Name,
Created: test.Created,
Updated: test.Updated,
})
}
if res.NextLink == nil || *res.NextLink == "" {
return tests, nil
}
if len(res.Value) == 0 {
return nil, errors.New("received empty load tests page with next link")
}
skip += pageSize
}
}
func (c *Client) listLoadTestsPage(
ctx context.Context, projectID int64, skip, top int32,
) (*k6cloud.LoadTestListResponse, error) {
res, hr, err := c.apiClient.LoadTestsAPI.
ProjectsLoadTestsRetrieve(c.authCtx(ctx), projectID).
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 command; concurrent modifications on the server can momentarily produce empty pages
- Confirm the project ID used actually belongs to your stack (K6_CLOUD_PROJECT_ID / --project-id)
- Upgrade k6 so the vendored cloud API client matches the deployed API version
- Capture the raw HTTP response with debug logging and escalate to Grafana support if persistent
Example fix
// before
var tests []k6cloud.LoadTest
for {
page, err := client.ListLoadTests(ctx, projectID)
if err != nil {
return err
}
tests = append(tests, page...)
}
// after: tolerate one empty-with-nextLink page by retrying the page once
tests, err := client.ListLoadTests(ctx, projectID)
if err != nil && strings.Contains(err.Error(), "empty load tests page") {
time.Sleep(2 * time.Second)
tests, err = client.ListLoadTests(ctx, projectID)
} Defensive patterns
Strategy: retry
Try / catch
tests, err := client.ListLoadTests(ctx, projectID)
if err != nil && strings.Contains(err.Error(), "empty load tests page") {
time.Sleep(2 * time.Second)
tests, err = client.ListLoadTests(ctx, projectID)
}
if err != nil {
return fmt.Errorf("listing load tests for project %d: %w", projectID, err)
} Prevention
- Avoid listing load tests while other automation concurrently creates/deletes tests in the same project
- Retry once on pagination-anomaly errors before treating them as fatal
- Keep k6 updated so client and server pagination contracts stay aligned
When it happens
Trigger: Calling Client.ListLoadTests for a projectID when the server returns 200 OK with Value=[] and a non-empty NextLink in the same LoadTestListResponse. The client-side inputs (projectID, skip/top paging) are well-formed; the response shape is what fails.
Common situations: Enumerating a project's load tests while tests are being created/deleted concurrently on the server, an API-side pagination bug, or a proxy rewriting the response. Usually transient and resolved by a retry.
Related errors
- received empty projects 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/d73c19820f375fe9.
Report an issue: GitHub.