# rpc error: code = FailedPrecondition desc = resource version mismatch: expected 42, got 41

- **ID:** `go/grpc-failed-precondition`
- **Domain:** go
- **Category:** data_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

The server rejected the operation because a precondition on the resource state was not met — typically optimistic concurrency control where the client's version/etag is stale relative to the current server state.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.x | active | — | — |

## Workarounds

1. **** (88% success)
   ```
   Re-fetch the latest resource, apply the mutation to the fresh copy, and retry with the new version:

for i := 0; i < 5; i++ {
    cur, err := client.Get(ctx, &pb.GetReq{Id: id})
    if err != nil { return err }
    cur.Data = newData
    _, err = client.Update(ctx, &pb.UpdateReq{Id: id, Data: newData, Version: cur.Version})
    if status.Code(err) != codes.FailedPrecondition { return err }
}
   ```
2. **** (80% success)
   ```
   Use an ETag/If-Match style conditional request and surface a conflict to the caller when it persists:

if status.Code(err) == codes.FailedPrecondition {
    return ErrConflict // let the caller resolve
}
   ```

## Dead Ends

- **** — The version is still stale; the server rejects every identical attempt with the same FailedPrecondition. (90% fail)
- **** — Removing the precondition bypasses concurrency control and risks last-writer-wins data loss. (70% fail)
