{"record":{"id":"c1bd29087ba3a114","repo":"hashicorp/terraform","slug":"wrapped-err-w","errorCode":null,"errorMessage":"wrapped err: %w","messagePattern":"wrapped err: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/grpcwrap/provider6.go","lineNumber":1075,"sourceCode":"\t\trangeStart += byteCount\n\t}\n}\n\nfunc (p *provider6) WriteStateBytes(srv tfplugin6.Provider_WriteStateBytesServer) error {\n\tvar typeName string\n\tvar stateId string\n\n\tstate := bytes.Buffer{}\n\tvar grpcErr error\n\tvar totalReceivedBytes int\n\tvar expectedTotalLength int64\n\tfor {\n\t\tchunk, err := srv.Recv()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tgrpcErr = fmt.Errorf(\"wrapped err: %w\", err)\n\t\t\tbreak\n\t\t}\n\t\tif expectedTotalLength == 0 {\n\t\t\t// On the first iteration\n\t\t\texpectedTotalLength = chunk.TotalLength // record expected length\n\t\t\tif chunk.Meta != nil {\n\t\t\t\t// We expect the Meta to be set on the first message, only\n\t\t\t\ttypeName = chunk.Meta.TypeName\n\t\t\t\tstateId = chunk.Meta.StateId\n\t\t\t} else {\n\t\t\t\tpanic(\"expected Meta to be set on first chunk sent to WriteStateBytes\")\n\t\t\t}\n\t\t}\n\n\t\tn, err := state.Write(chunk.Bytes)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error writing state: %w\", err)\n\t\t}","sourceCodeStart":1057,"sourceCodeEnd":1093,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/grpcwrap/provider6.go#L1057-L1093","documentation":"Returned by WriteStateBytes (internal/grpcwrap/provider6.go:1075) when the bidirectional stream's srv.Recv() returns an error other than io.EOF while reading chunked state-upload messages. The error is wrapped with %w and stored in grpcErr, then returned after the receive loop breaks. The underlying cause is a transport-level stream failure (connection reset, cancellation, deadline, broken pipe).","triggerScenarios":"During a state-store upload over the WriteStateBytes server-streaming RPC, the client (Terraform core) drops the connection, the gRPC context is cancelled, or the network link breaks mid-stream; srv.Recv() then returns a non-EOF error and it is wrapped here.","commonSituations":"Unstable network to a remote state store, gRPC keepalive/timeout killing a long upload, context cancellation (e.g. user Ctrl-C during apply), state store backend restart mid-write, or proxy/load-balancer closing idle streams.","solutions":["Inspect the wrapped error (errors.Unwrap) to distinguish context cancellation from a transport error.","Retry the operation: state writes are retried by Terraform core; ensure the network/state store is healthy.","Increase gRPC keepalive/timeout allowances if uploads are large and slow.","Check state store backend availability and that the connection is not behind an aggressive proxy."],"exampleFix":"// before\nfor {\n    chunk, err := srv.Recv()\n    if err == io.EOF { break }\n    if err != nil {\n        grpcErr = fmt.Errorf(\"wrapped err: %w\", err)  // connection reset by peer\n        break\n    }\n}\n\n// after (caller side: retry on transient transport error)\nif errors.Is(err, context.Canceled) || isTransient(err) {\n    // retry the state upload\n}","handlingStrategy":"retry","validationCode":"// Before uploading, verify the stream/context is alive:\nfunc streamAlive(ctx context.Context) bool {\n    return ctx.Err() == nil\n}","typeGuard":"func isTransientRecvErr(err error) bool {\n    return errors.Is(err, context.Canceled) ||\n        errors.Is(err, context.DeadlineExceeded) ||\n        status.Code(err) == codes.Unavailable\n}","tryCatchPattern":"// Retry the whole WriteStateBytes upload on transient transport errors:\nvar lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    err := uploadState(ctx, bytes)\n    if err == nil { return nil }\n    lastErr = err\n    if !isTransientRecvErr(err) { break }\n}\nreturn lastErr","preventionTips":["Size gRPC keepalive/timeouts to the largest expected state upload.","Retry idempotent state writes on transient transport errors.","Distinguish context.Canceled (user) from real network failures.","Avoid aggressive proxies that close idle streaming connections."],"tags":["grpc","state-store","streaming","network","io"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}