{"record":{"id":"2de4db0707ec2161","repo":"grafana/k6","slug":"total-duration-w","errorCode":null,"errorMessage":"total_duration: %w","messagePattern":"total_duration: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloudapi/provisioning/api.go","lineNumber":210,"sourceCode":"\t// Generate idempotency key: 8 random bytes hex-encoded (16 chars).\n\tvar key [8]byte\n\tif _, err := rand.Read(key[:]); err != nil {\n\t\treturn nil, fmt.Errorf(\"generating idempotency key: %w\", err)\n\t}\n\n\t// SDK adapter: unmarshal json.RawMessage → map[string]any.\n\tvar opts map[string]any\n\tif err := json.Unmarshal(req.Options, &opts); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshalling options for SDK: %w\", err)\n\t}\n\n\tmaxVUs, err := toInt32(req.MaxVUs)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"max_vus: %w\", err)\n\t}\n\ttotalDuration, err := toInt32(req.TotalDuration)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"total_duration: %w\", err)\n\t}\n\n\tsdkReq := k6cloud.NewStartLocalExecutionTestRequest(opts, maxVUs, totalDuration)\n\n\tif req.ArchiveSize > 0 {\n\t\tv, err := toInt32(req.ArchiveSize)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"archive_size: %w\", err)\n\t\t}\n\t\tsdkReq.SetArchiveSize(v)\n\t} else {\n\t\tsdkReq.SetArchiveSizeNil()\n\t}\n\n\tres, hr, err := c.apiClient.ProvisioningAPI.\n\t\tStartLocalExecutionTest(c.authCtx(ctx), loadTestID).\n\t\tK6IdempotencyKey(hex.EncodeToString(key[:])).\n\t\tStartLocalExecutionTestRequest(sdkReq).","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/cloudapi/provisioning/api.go#L192-L228","documentation":"Client.StartLocalExecution (internal/cloudapi/provisioning/api.go:210) converts req.TotalDuration (seconds, int64) to int32 for the cloud API schema. int32 max is ~2.1 billion seconds (~68 years), so a real duration never overflows; hitting this error means the value is wrong — typically a unit confusion (milliseconds or nanoseconds passed as seconds) or a garbage/negative sentinel.","triggerScenarios":"TotalDuration computed by summing executor durations with the wrong unit, a duration value derived from an unchecked env/flag, or an overflowed negative number from caller arithmetic.","commonSituations":"Custom tooling that translates durations and drops a division by time.Second; options with enormous -d values from templating mistakes.","solutions":["Verify the duration is expressed in seconds before building the request","Range-check the computed total against a sane maximum (e.g. 30 days) and fail early with a clear message","Re-run k6 inspect on the script to see the effective duration options","Fix the upstream duration calculation rather than catching the error"],"exampleFix":"// before\nreq := provisioning.StartLocalExecutionRequest{\n\tTotalDuration: totalDurationMs, // oops: milliseconds, not seconds\n}\n\n// after\ntotalSeconds := int64(totalDuration / time.Second)\nif totalSeconds <= 0 || totalSeconds > 30*24*3600 {\n\treturn fmt.Errorf(\"implausible total duration: %ds\", totalSeconds)\n}\nreq := provisioning.StartLocalExecutionRequest{TotalDuration: totalSeconds}","handlingStrategy":"validation","validationCode":"totalSeconds := int64(total / time.Second)\nif totalSeconds <= 0 || totalSeconds > 365*24*3600 {\n\treturn fmt.Errorf(\"total_duration %ds implausible; check units\", totalSeconds)\n}","typeGuard":"func fitsInt32(v int64) bool { return v >= math.MinInt32 && v <= math.MaxInt32 }","tryCatchPattern":"if err := client.StartLocalExecution(ctx, id, req); err != nil {\n\tif strings.HasPrefix(err.Error(), \"total_duration:\") {\n\t\t// suspect a unit mismatch (ms/ns passed as seconds) upstream\n\t}\n\treturn err\n}","preventionTips":["Convert durations with explicit time.Second division in exactly one place","Sanity-check computed durations against a human-plausible maximum","Unit-test the duration computation, not just the error path"],"tags":["validation","int32","overflow","duration","units"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}