Skip to content

fix: use HYPERCODE_REDIS_URL env var in MultiTierCache default (#196)#196

Open
welshDog wants to merge 1 commit intomainfrom
fix/multi-tier-cache-redis-auth
Open

fix: use HYPERCODE_REDIS_URL env var in MultiTierCache default (#196)#196
welshDog wants to merge 1 commit intomainfrom
fix/multi-tier-cache-redis-auth

Conversation

@welshDog
Copy link
Copy Markdown
Owner

@welshDog welshDog commented May 1, 2026

🐛 Problem

MultiTierCache.__init__ had a hardcoded default:

redis_url: str = "redis://redis:6379/1"  # no auth!

On Railway, Redis requires a password (from HYPERCODE_REDIS_URL). The hardcoded URL had no password → server returned NOAUTH Authentication required → app fell back to local-cache-only mode.

Meanwhile main.py (metrics Redis client) was already using settings.HYPERCODE_REDIS_URL correctly — so you had two Redis clients using two different configs.

✅ Fix

Changed redis_url default to None and resolve via env var — same pattern as the working client:

def __init__(
    self,
    local_size: int = 1000,
    local_ttl: int = 300,
    redis_url: str | None = None,  # ← resolve from env
):
    self.redis_url = redis_url or os.getenv("HYPERCODE_REDIS_URL", "redis://redis:6379/1")

📋 Impact

  • Eliminates Redis connection failed: Authentication required warning on Railway
  • MultiTierCache will now connect to Redis with full auth
  • redis://redis:6379/1 still works as a last-resort local fallback
  • Zero breaking changes — existing callers unaffected

🧪 Expected log change after deploy

Before: ⚠️ Redis connection failed: Authentication required.. Using local cache only.
After: ✅ Redis cache connected

Summary by CodeRabbit

  • Chores
    • Cache configuration now supports optional environment variable for Redis connection URL, providing sensible automatic defaults when explicit configuration is not supplied.
    • Improves operational flexibility by simplifying configuration management across different deployment environments.
    • Reduces setup complexity for standard deployments whilst maintaining configurability for specialised environments.
    • Documentation updated to reflect the new configuration approach and available options.

The __init__ default redis_url was hardcoded to redis://redis:6379/1
with no auth, causing NOAUTH Authentication required on Railway where
Redis requires a password.

Fix: default to None and resolve via os.getenv("HYPERCODE_REDIS_URL")
with the old URL as last-resort fallback — same pattern as main.py.

Also fixes get_cache() call site to pass the env var explicitly.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

The MultiTierCache class now accepts an optional redis_url parameter that defaults to None. When not provided, the connection URL is resolved from the HYPERCODE_REDIS_URL environment variable, falling back to redis://redis:6379/1. The singleton initialization documentation has been updated accordingly.

Changes

Cohort / File(s) Summary
Redis Configuration
backend/app/cache/multi_tier.py
Modified MultiTierCache.__init__() to accept optional redis_url parameter (str | None) instead of a default string value. Connection URL now derived from HYPERCODE_REDIS_URL environment variable with fallback to redis://redis:6379/1 when omitted.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A rabbit hops through config land,
Where env vars lend a helping hand,
No hardcoded paths to slow us down,
Just flexibility all around! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main change: using the HYPERCODE_REDIS_URL environment variable as the default for MultiTierCache's redis_url parameter.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/multi-tier-cache-redis-auth

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 OpenGrep (1.20.0)
backend/app/cache/multi_tier.py

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

�[1m Loading rules from local config...�[0m


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/app/cache/multi_tier.py`:
- Line 47: self.redis_url is set using os.getenv which returns an empty string
if HYPERCODE_REDIS_URL is present but empty, causing silent fallback to local
cache; change the assignment in the constructor to treat empty/whitespace values
as unset by checking truthiness/stripped content. Concretely, compute candidate
= redis_url if redis_url and redis_url.strip() else
os.getenv("HYPERCODE_REDIS_URL") and then set self.redis_url = candidate.strip()
if candidate and candidate.strip() else "redis://redis:6379/1" so that both an
empty env var and an empty argument correctly fall back to the default.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bc326467-7326-4219-9371-282781a6e424

📥 Commits

Reviewing files that changed from the base of the PR and between 7e16476 and b02c2f1.

📒 Files selected for processing (1)
  • backend/app/cache/multi_tier.py

"""
self.local_cache = TTLCache(maxsize=local_size, ttl=local_ttl)
self.redis_url = redis_url
self.redis_url = redis_url or os.getenv("HYPERCODE_REDIS_URL", "redis://redis:6379/1")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current expression behaviour when env var is empty.
python - <<'PY'
import os
os.environ["HYPERCODE_REDIS_URL"] = ""
redis_url = None
resolved = redis_url or os.getenv("HYPERCODE_REDIS_URL", "redis://redis:6379/1")
print("resolved =", repr(resolved))
# Expected with current code: '' (shows fallback is skipped)
PY

Repository: welshDog/HyperCode-V2.4

Length of output: 81


🏁 Script executed:

git ls-files backend/app/cache/multi_tier.py

Repository: welshDog/HyperCode-V2.4

Length of output: 99


🏁 Script executed:

cat -n backend/app/cache/multi_tier.py | head -60 | tail -25

Repository: welshDog/HyperCode-V2.4

Length of output: 1116


🏁 Script executed:

rg "HYPERCODE_REDIS_URL|redis_url" -A 2 -B 2

Repository: welshDog/HyperCode-V2.4

Length of output: 50381


Empty HYPERCODE_REDIS_URL bypasses fallback to default Redis URL.

When the environment variable is present but empty or whitespace-only, os.getenv() returns the empty value before the default is ever evaluated. This causes self.redis_url to be set to an empty string instead of falling back to redis://redis:6379/1, silently disabling Redis connectivity and reverting to local-cache-only mode.

Suggested fix
-        self.redis_url = redis_url or os.getenv("HYPERCODE_REDIS_URL", "redis://redis:6379/1")
+        configured_url = (redis_url or os.getenv("HYPERCODE_REDIS_URL") or "").strip()
+        self.redis_url = configured_url or "redis://redis:6379/1"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
self.redis_url = redis_url or os.getenv("HYPERCODE_REDIS_URL", "redis://redis:6379/1")
configured_url = (redis_url or os.getenv("HYPERCODE_REDIS_URL") or "").strip()
self.redis_url = configured_url or "redis://redis:6379/1"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/app/cache/multi_tier.py` at line 47, self.redis_url is set using
os.getenv which returns an empty string if HYPERCODE_REDIS_URL is present but
empty, causing silent fallback to local cache; change the assignment in the
constructor to treat empty/whitespace values as unset by checking
truthiness/stripped content. Concretely, compute candidate = redis_url if
redis_url and redis_url.strip() else os.getenv("HYPERCODE_REDIS_URL") and then
set self.redis_url = candidate.strip() if candidate and candidate.strip() else
"redis://redis:6379/1" so that both an empty env var and an empty argument
correctly fall back to the default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant