{"record":{"id":"3fe6636ecfa09a1d","repo":"grafana/k6","slug":"unexpected-nil-response-from-createorfindloadtest","errorCode":null,"errorMessage":"unexpected nil response from CreateOrFindLoadTest","messagePattern":"unexpected nil response from CreateOrFindLoadTest","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloudapi/v6/api.go","lineNumber":271,"sourceCode":"\t\tName(name).\n\t\tExecute()\n\tdefer closeResponse(hr, &err)\n\n\tif err := CheckResponse(hr, err); err != nil {\n\t\tvar rerr ResponseError\n\t\tif errors.As(err, &rerr) && rerr.Response != nil && rerr.Response.StatusCode == http.StatusConflict {\n\t\t\tlt, err := c.findTestByName(ctx, projectID, name)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\treturn lt.GetId(), nil\n\t\t}\n\t\treturn 0, err\n\t}\n\tif res == nil {\n\t\t// The SDK getters return zero values on a nil receiver, so guard\n\t\t// against silently producing a bogus 0 id and report it clearly.\n\t\treturn 0, errors.New(\"unexpected nil response from CreateOrFindLoadTest\")\n\t}\n\n\treturn res.GetId(), nil\n}\n\n// UploadTest creates or updates a cloud load test's script.\nfunc (c *Client) UploadTest(\n\tctx context.Context, name string, projectID int64, arc *lib.Archive,\n) (*k6cloud.LoadTestApiModel, error) {\n\tlt, err := c.createTest(ctx, name, projectID, arc)\n\tif err == nil {\n\t\treturn lt, nil\n\t}\n\tvar rerr ResponseError\n\tif !errors.As(err, &rerr) || rerr.Response == nil || rerr.Response.StatusCode != http.StatusConflict {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/cloudapi/v6/api.go#L253-L289","documentation":"A defensive guard in CreateOrFindLoadTest: the generated OpenAPI client's getters (res.GetId()) return zero values when called on a nil receiver, so if Execute() returned (nil, nil) the client would silently report a load-test ID of 0 and later calls would target a nonexistent test. This error converts that silent corruption into a loud failure.","triggerScenarios":"The k6-cloud-openapi-client-go LoadTestsCreate call returns err == nil but a nil *LoadTestLightWithLatest response. Realistically only seen with custom/mock HTTP transports, SDK deserialization edge cases, or a patched/older SDK version.","commonSituations":"Unit tests with mocked cloud API transports that forget to return a body; running a k6 build against a forked k6-cloud-openapi-client-go; extremely rare SDK/transport anomalies against the real API.","solutions":["Retry the `k6 cloud run` command; if it persists, capture debug HTTP output","If you maintain a custom transport/mock, make sure 2xx responses include a valid JSON body the SDK can deserialize","Upgrade k6 so the vendored SDK version matches the API contract","Report to k6 maintainers with the exact k6 version and response body"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// The SDK getters return zero values on a nil receiver, so callers that\n// bypass this client must nil-check the model before reading fields.\nfunc validLoadTest(lt *k6cloud.LoadTestLightWithLatest) bool {\n    return lt != nil && lt.Id != nil && *lt.Id > 0\n}","tryCatchPattern":"id, err := client.CreateOrFindLoadTest(ctx, name, projectID, arc)\nif err != nil {\n    if strings.Contains(err.Error(), \"unexpected nil response\") {\n        // SDK/transport anomaly: safe to retry the create-or-find once\n        id, err = client.CreateOrFindLoadTest(ctx, name, projectID, arc)\n    }\n    if err != nil {\n        return 0, err\n    }\n}","preventionTips":["Never trust zero values from generated OpenAPI getters — nil-check response models","When mocking the cloud API in tests, always return a deserializable body on 2xx","Treat this error as an SDK-contract bug worth reporting upstream, not a config issue"],"tags":["cloud","api","nil-guard","sdk","go"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}