{"record":{"id":"45e0861d33b1bcd3","repo":"instructure/canvas-lms","slug":"redis-method-command-is-not-supported-by-twemproxy-and-so","errorCode":null,"errorMessage":"Redis method `#{command}` is not supported by Twemproxy, and so shouldn't be used in Canvas","messagePattern":"Redis method `#(.+?)` is not supported by Twemproxy, and so shouldn't be used in Canvas","errorType":"exception","errorClass":"CanvasCache::Redis::UnsupportedRedisMethod","httpStatus":null,"severity":"error","filePath":"gems/canvas_cache/lib/redis_client/twemproxy.rb","lineNumber":103,"sourceCode":"      slowlog\n      sync\n    ].freeze\n\n    def call(command, _config)\n      check_command(command.first.to_s)\n      super\n    end\n\n    def call_pipelined(commands, _config)\n      commands.each do |command|\n        check_command(command.first.to_s)\n      end\n      super\n    end\n\n    def check_command(command)\n      if UNSUPPORTED_METHODS.include?(command)\n        raise CanvasCache::Redis::UnsupportedRedisMethod,\n              \"Redis method `#{command}` is not supported by Twemproxy, and so shouldn't be used in Canvas\"\n      end\n      if ALLOWED_UNSUPPORTED.include?(command) && !RedisClient.dangerous_redis_methods_allowed? && GuardRail.environment != :deploy\n        raise CanvasCache::Redis::UnsupportedRedisMethod,\n              \"Redis method `#{command}` is potentially dangerous, and should only be called from console, and only if you fully understand the consequences. If you're sure, retry after wrapping in `RedisClient.with_dangerous_redis_methods`\"\n      end\n    end\n  end\nend\n","sourceCodeStart":85,"sourceCodeEnd":113,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/gems/canvas_cache/lib/redis_client/twemproxy.rb#L85-L113","documentation":"canvas_cache's Twemproxy adapter blocks Redis commands that Twemproxy cannot route (per UNSUPPORTED_METHODS, e.g. KEYS, SCAN-like multi-node ops, transactions) by raising UnsupportedRedisMethod. Because Canvas runs Redis behind Twemproxy in production, unsupported commands would silently misbehave, so they're rejected with a clear message instead.","triggerScenarios":"Calling an unsupported Redis command (e.g. redis.keys('*'), multi/exec, script ops in some setups) through a redis-client configured with the Twemproxy adapter; check_command is invoked by call and call_pipelined.","commonSituations":"Debugging in console against production-style proxy config; gems/libraries issuing commands that assume direct Redis access; using methods that work locally but not behind Twemproxy after deploying.","solutions":["Rewrite the code to use supported commands (e.g. SCAN via per-key patterns, pipelined gets) instead of blocked ones","Use a direct (non-Twemproxy) Redis connection for administrative/maintenance commands","Set RedisClient.dangerous_redis_methods_allowed? / run in GuardRail :deploy environment only if the command is genuinely needed and safe","Check UNSUPPORTED_METHODS in the gem to confirm which commands are blocked and pick alternatives"],"exampleFix":"// before\nkeys = redis.keys('course:cities:*')\n// after\nkeys = redis.scan_each(match: 'course:cities:*').to_a # supported variant\n","handlingStrategy":"validation","validationCode":"UNSAFE = %w[KEYS SCAN MULTI EXEC].freeze\nraise UnsupportedRedisMethod, cmd if UNSAFE.include?(cmd.to_s.upcase)","typeGuard":null,"tryCatchPattern":"begin\n  redis.keys(pattern)\nrescue CanvasCache::Redis::UnsupportedRedisMethod => e\n  Rails.logger.warn(\"twemproxy: #{e.message}\")\n  fallback_supported_scan(pattern)\nend","preventionTips":["Review canvas_cache UNSUPPORTED_METHODS before using exotic Redis commands","Prefer pipelined simple commands over multi-key/transactional ops","Test redis-dependent code against a Twemproxy-proxied instance"],"tags":["redis","twemproxy","unsupported-command"],"backgroundTag":"operation-not-supported","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}