{"record":{"id":"e42cd0917f14848c","repo":"Tencent/WeKnora","slug":"failed-to-delete-redis-key-w","errorCode":null,"errorMessage":"failed to delete Redis key: %w","messagePattern":"failed to delete Redis key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/web_search_state.go","lineNumber":137,"sourceCode":"\n\tlogger.Infof(ctx, \"Cleaning temporary KB for session %s: %s\", sessionID, state.KBID)\n\n\t// Delete all knowledge items\n\tfor _, kid := range state.KnowledgeIDs {\n\t\tif delErr := s.knowledgeService.DeleteKnowledge(ctx, kid); delErr != nil {\n\t\t\tlogger.Warnf(ctx, \"Failed to delete temp knowledge %s: %v\", kid, delErr)\n\t\t}\n\t}\n\n\t// Delete the knowledge base\n\tif delErr := s.knowledgeBaseService.DeleteKnowledgeBase(ctx, state.KBID); delErr != nil {\n\t\tlogger.Warnf(ctx, \"Failed to delete temp knowledge base %s: %v\", state.KBID, delErr)\n\t}\n\n\t// Delete the Redis key\n\tif delErr := s.redisClient.Del(ctx, stateKey).Err(); delErr != nil {\n\t\tlogger.Warnf(ctx, \"Failed to delete Redis key %s: %v\", stateKey, delErr)\n\t\treturn fmt.Errorf(\"failed to delete Redis key: %w\", delErr)\n\t}\n\n\tlogger.Infof(ctx, \"Successfully cleaned up temporary KB for session %s\", sessionID)\n\treturn nil\n}\n","sourceCodeStart":119,"sourceCodeEnd":143,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/web_search_state.go#L119-L143","documentation":"DeleteWebSearchTempKBState cleans up a temporary knowledge base and its Redis state key. If s.redisClient.Del fails, the function logs a warning and wraps the Redis error as 'failed to delete Redis key: %w'. This signals that cleanup only partially succeeded: the temp KB may be gone but the Redis state entry persists.","triggerScenarios":"Calling DeleteWebSearchTempKBState when Redis is down, connection dropped, the key is on a read-only replica, or the client lacks DELETE permission on the key (e.g. ACL restrictions or a protected prefix).","commonSituations":"Redis restarted or evicted connections mid-cleanup; network partition between app and Redis; wrong Redis database/ACL in staging vs production; key expired between read and delete causing unexpected client errors.","solutions":["Check Redis connectivity (redis-cli ping) and the app's Redis logs for the underlying delErr.","Retry the delete; Del failures here are usually transient connection issues.","Verify the Redis user's ACL permits DELETE on the stateKey pattern.","If the key may already be gone, treat redis.Nil/'key not found' as success and only fail on real errors.","As a fallback, rely on TTL expiry for orphaned state keys and alert on repeated cleanup failures."],"exampleFix":"// before\nif delErr := s.redisClient.Del(ctx, stateKey).Err(); delErr != nil {\n\treturn fmt.Errorf(\"failed to delete Redis key: %w\", delErr)\n}\n// after\nif delErr := s.redisClient.Del(ctx, stateKey).Err(); delErr != nil && delErr != redis.Nil {\n\treturn fmt.Errorf(\"failed to delete Redis key: %w\", delErr)\n}","handlingStrategy":"try-catch","validationCode":"if err := s.redisClient.Ping(ctx).Err(); err != nil {\n\t// degrade: skip Redis cleanup and rely on TTL expiry\n}","typeGuard":null,"tryCatchPattern":"if err := svc.DeleteWebSearchTempKBState(ctx, sessionID); err != nil {\n\tif strings.Contains(err.Error(), \"failed to delete Redis key\") {\n\t\tlogger.Warnf(ctx, \"state cleanup deferred; TTL will expire key: %v\", err)\n\t\treturn nil // or queue a retry\n\t}\n\treturn err\n}","preventionTips":["Set a TTL on state keys at write time so failed deletes self-heal.","Monitor Redis health and alerts so cleanup windows don't coincide with outages.","Treat redis.Nil as success in delete paths.","Grant the app's Redis user DELETE permission via ACL.","Retry transient Del failures with backoff before surfacing an error."],"tags":["redis","cleanup","network","state"],"backgroundTag":"redis-operation-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}