{"id":"658862f692a1cf89","repo":"go-redis/redis","slug":"failed-to-mark-connection-as-unusable-w","errorCode":null,"errorMessage":"failed to mark connection as unusable: %w","messagePattern":"failed to mark connection as unusable: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pool/conn.go","lineNumber":909,"sourceCode":"\t// But in some edge cases or tests, it might be in IDLE or CREATED state\n\t// The pool will detect this state change and preserve it (not overwrite with IDLE)\n\t// Use predefined slice to avoid allocation\n\tfinalState, err := cn.stateMachine.TryTransition(validFromCreatedInUseOrIdle, StateUnusable)\n\tif err != nil {\n\t\t// Check if already in UNUSABLE state (race condition or retry)\n\t\t// ShouldHandoff should be false now, but check just in case\n\t\tif finalState == StateUnusable && !cn.ShouldHandoff() {\n\t\t\t// Already unusable - this is fine, keep the new handoff state\n\t\t\treturn nil\n\t\t}\n\t\t// Restore the original handoff state only if nothing else changed it\n\t\t// since our CAS above. A concurrent handoff worker may have completed\n\t\t// the handoff and run ClearHandoffState in this window; a plain Store\n\t\t// would clobber that, resurrecting ShouldHandoff=true and wedging the\n\t\t// connection so it can never be acquired again. The CAS leaves the\n\t\t// worker's state intact when it has taken over.\n\t\tcn.handoffStateAtomic.CompareAndSwap(newState, currentState)\n\t\treturn fmt.Errorf(\"failed to mark connection as unusable: %w\", err)\n\t}\n\treturn nil\n}\n\n// GetID returns the unique identifier for this connection.\nfunc (cn *Conn) GetID() uint64 {\n\treturn cn.id\n}\n\n// GetStateMachine returns the connection's state machine for advanced state management.\n// This is primarily used by internal packages like maintnotifications for handoff processing.\nfunc (cn *Conn) GetStateMachine() *ConnStateMachine {\n\treturn cn.stateMachine\n}\n\n// TryAcquire attempts to acquire the connection for use.\n// This is an optimized inline method for the hot path (Get operation).\n//","sourceCodeStart":891,"sourceCodeEnd":927,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/internal/pool/conn.go#L891-L927","documentation":"Error \"failed to mark connection as unusable: %w\" thrown in go-redis/redis.","triggerScenarios":"Thrown at internal/pool/conn.go:909 when the library encounters an invalid state.","commonSituations":"Let the pool own conn state transitions; do not hold conn references across operations.","solutions":["Retry the operation on a fresh connection; the original conn could not be marked unusable","Check the wrapped error for pool-level issues (pool closed, conn already removed)"],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}