{"record":{"id":"5950f2afbaa92c40","repo":"grafana/k6","slug":"create-or-find-load-test-w","errorCode":null,"errorMessage":"create or find load test: %w","messagePattern":"create or find load test: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloudapi/provisioning/provision.go","lineNumber":59,"sourceCode":"type ProvisionResult struct {\n\t// TestRunID is the ID of the provisioned test run.\n\tTestRunID int64\n\n\t// TestRunDetailsPageURL is the URL of the test run details page.\n\tTestRunDetailsPageURL string\n\n\t// RuntimeConfig carries the metrics, secrets, and token\n\t// configuration returned by the provisioning API.\n\tRuntimeConfig RuntimeConfig\n}\n\n// ProvisionLocalExecution orchestrates the full local-execution\n// provisioning flow: CreateOrFindLoadTest → StartLocalExecution →\n// optional UploadArchive → WaitForTestRunReady.\nfunc (c *Client) ProvisionLocalExecution(ctx context.Context, params ProvisionParams) (*ProvisionResult, error) {\n\tloadTestID, err := c.v6Client.CreateOrFindLoadTest(ctx, params.ProjectID, params.Name)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create or find load test: %w\", err)\n\t}\n\n\t// Serialise archive once to get its byte-length for the\n\t// start_local_execution body. The same buffer is reused for\n\t// the S3 upload to avoid a second serialisation.\n\tvar (\n\t\tarchiveSize  int64\n\t\tarchiveBytes []byte\n\t)\n\tif params.Archive != nil {\n\t\tvar buf bytes.Buffer\n\t\tif err := params.Archive.Write(&buf); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"serialising archive: %w\", err)\n\t\t}\n\t\tarchiveSize = int64(buf.Len())\n\t\tarchiveBytes = buf.Bytes()\n\t}\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/cloudapi/provisioning/provision.go#L41-L77","documentation":"The first step of Client.ProvisionLocalExecution (internal/cloudapi/provisioning/provision.go:59) calls the v6 CreateOrFindLoadTest(projectID, name); this error wraps its failure. The wrapped error comes from v6.CheckResponse: 401/403 for a bad/unauthorized token, 404 for an unknown project, other 4xx/5xx bodies, or a transport error.","triggerScenarios":"Token lacking access to the given projectID; a stale or wrong K6_CLOUD_PROJECT_ID; token issued for a different org than the host/stack; network failure reaching the cloud API.","commonSituations":"CI with rotated tokens but old project IDs; Grafana Cloud stack migration leaving env vars stale; wrong host (different region/stack) combined with a valid token.","solutions":["Read the wrapped error's status/body — 401/403 vs 404 points to token vs project","Verify the project ID in the Grafana Cloud UI and match it to K6_CLOUD_PROJECT_ID","Confirm the token belongs to the same org/stack as the configured host","Validate the token upfront with v6 Client.ValidateToken to fail fast with a clearer message"],"exampleFix":"# before\nexport K6_CLOUD_PROJECT_ID=123  # stale after migration\nk6 run --local-execution script.js\n\n# after\nexport K6_CLOUD_PROJECT_ID=456  # correct project in current org\nk6 run --local-execution script.js","handlingStrategy":"validation","validationCode":"if _, err := v6Client.ValidateToken(ctx, stackURL); err != nil {\n\treturn fmt.Errorf(\"token validation failed; fix credentials before provisioning: %w\", err)\n}\nif params.ProjectID < 1 {\n\treturn errors.New(\"project ID must be a positive number from the target stack\")\n}","typeGuard":"func isAuthOrProjectError(err error) bool {\n\tvar re *cloudapi.ResponseError\n\treturn errors.As(err, &re) && (re.StatusCode == 401 || re.StatusCode == 403 || re.StatusCode == 404)\n}","tryCatchPattern":"res, err := client.ProvisionLocalExecution(ctx, params)\nif err != nil {\n\tif strings.Contains(err.Error(), \"create or find load test\") {\n\t\t// unwrap for status: 401/403 = token scope, 404 = project ID\n\t}\n\treturn err\n}","preventionTips":["Validate the token with ValidateToken before any provisioning call","Cross-check K6_CLOUD_PROJECT_ID against the org/stack owning the token","Keep host, org, and project env vars in one versioned place to avoid drift"],"tags":["cloud-api","auth","project","provisioning","configuration"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}