{"id":"9541bee0ba2d63bd","repo":"go-redis/redis","slug":"w-cannot-transition-from-s-to-s-valid-from","errorCode":null,"errorMessage":"%w: cannot transition from %s to %s (valid from: %v)","messagePattern":"%w: cannot transition from (.+?) to (.+?) \\(valid from: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pool/conn_state.go","lineNumber":192,"sourceCode":"\tfor _, fromState := range validFromStates {\n\t\t// Try to atomically swap from fromState to targetState\n\t\t// If successful, we won the race and can proceed\n\t\tif sm.state.CompareAndSwap(uint32(fromState), uint32(targetState)) {\n\t\t\t// Success! We transitioned atomically\n\t\t\t// Hot path optimization: only check for waiters if transition succeeded\n\t\t\t// This avoids atomic load on every Get/Put when no waiters exist\n\t\t\tif sm.waiterCount.Load() > 0 {\n\t\t\t\tsm.notifyWaiters()\n\t\t\t}\n\t\t\treturn targetState, nil\n\t\t}\n\t}\n\n\t// All CAS attempts failed - state is not valid for this transition\n\t// Return the current state so caller can decide what to do\n\t// Note: This error path allocates, but it's the exceptional case\n\tcurrentState := sm.GetState()\n\treturn currentState, fmt.Errorf(\"%w: cannot transition from %s to %s (valid from: %v)\",\n\t\tErrInvalidStateTransition, currentState, targetState, validFromStates)\n}\n\n// Transition unconditionally transitions to the target state.\n// Use with caution - prefer AwaitAndTransition or TryTransition for safety.\n// This is useful for error paths or when you know the transition is valid.\nfunc (sm *ConnStateMachine) Transition(targetState ConnState) {\n\tsm.state.Store(uint32(targetState))\n\tsm.notifyWaiters()\n}\n\n// AwaitAndTransition waits for the connection to reach one of the valid states,\n// then atomically transitions to the target state.\n// Returns the current state after the transition attempt and an error if the operation failed.\n// The returned state is the CURRENT state (after the attempt), not the previous state.\n// Returns error if timeout expires or context is cancelled.\n//\n// This method implements FIFO fairness - the first caller to wait gets priority","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/internal/pool/conn_state.go#L174-L210","documentation":"Error \"%w: cannot transition from %s to %s (valid from: %v)\" thrown in go-redis/redis.","triggerScenarios":"Thrown at internal/pool/conn_state.go:192 when the library encounters an invalid state.","commonSituations":"Centralize conn state changes in the state machine API rather than setting state ad hoc.","solutions":["Drive the connection through valid state transitions only (see the valid-from list in the error)","Reset or replace the connection when it reaches an unexpected state"],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}