ruvnet/RuView · critical · ValueError

Database URL must be configured for non-development environm

Error message

Database URL must be configured for non-development environments

What it means

Raised by Settings.get_database_url() in archive/v1/src/config/settings.py when no usable database configuration exists. The method first checks database_url, then the db_host+db_name+db_user triple, then a SQLite default for development, then the SQLite failsafe (enable_database_failsafe, default true). The ValueError fires only when all four paths fail, i.e. a non-development environment with no PostgreSQL coordinates and the failsafe deliberately disabled.

Source

Thrown at archive/v1/src/config/settings.py:290

    def get_database_url(self) -> str:
        """Get database URL with fallback."""
        if self.database_url:
            return self.database_url
        
        # Build URL from individual components if available
        if self.db_host and self.db_name and self.db_user:
            password_part = f":{self.db_password}" if self.db_password else ""
            return f"postgresql://{self.db_user}{password_part}@{self.db_host}:{self.db_port}/{self.db_name}"
        
        # Default SQLite database for development
        if self.is_development:
            return f"sqlite:///{self.data_storage_path}/wifi_densepose.db"
        
        # SQLite failsafe for production if enabled
        if self.enable_database_failsafe:
            return f"sqlite:///{self.sqlite_fallback_path}"
        
        raise ValueError("Database URL must be configured for non-development environments")
    
    def get_sqlite_fallback_url(self) -> str:
        """Get SQLite fallback database URL."""
        return f"sqlite:///{self.sqlite_fallback_path}"
    
    def get_redis_url(self) -> Optional[str]:
        """Get Redis URL with fallback."""
        if not self.redis_enabled:
            return None
            
        if self.redis_url:
            return self.redis_url
        
        # Build URL from individual components
        password_part = f":{self.redis_password}@" if self.redis_password else ""
        return f"redis://{password_part}{self.redis_host}:{self.redis_port}/{self.redis_db}"
    
    def get_cors_config(self) -> Dict[str, Any]:

View on GitHub (pinned to 4685618388)

Solutions

  1. Set DATABASE_URL (e.g. postgresql://user:pass@host:5432/dbname) for the non-development environment — this is the intended production path.
  2. Alternatively provide the full component triple: DB_HOST, DB_NAME, and DB_USER (with DB_PASSWORD as needed); all three must be present.
  3. If a local file DB is acceptable, leave enable_database_failsafe=true (the default) so SQLite at sqlite_fallback_path is used instead of raising.
  4. For real production, treat the failsafe as a hazard (silent data in SQLite) and instead make startup fail: keep the error, fix the env, and add a startup preflight check that verifies database_url exists when environment != development.

Example fix

# before
ENVIRONMENT=production
# DATABASE_URL unset, DB_HOST/DB_NAME/DB_USER incomplete
ENABLE_DATABASE_FAILSAFE=false
url = settings.get_database_url()  # ValueError

# after
ENVIRONMENT=production
DATABASE_URL=postgresql://wifi:secret@db.internal:5432/wifi_densepose
url = settings.get_database_url()
Defensive patterns

Strategy: try-catch

Validate before calling

required_db = settings.database_url or (
    settings.db_host and settings.db_name and settings.db_user
)
if settings.environment != 'development' and not required_db:
    raise SystemExit(
        'DATABASE_URL (or DB_HOST+DB_NAME+DB_USER) is required for '
        f'environment={settings.environment}'
    )

Try / catch

try:
    url = settings.get_database_url()
except ValueError as e:
    if 'non-development' in str(e):
        log.error('No database configured for %s; refusing to fall back to SQLite',
                  settings.environment)
        raise
    raise

Prevention

When it happens

Trigger: Calling settings.get_database_url() with: environment set to production/testing, database_url unset, at least one of db_host/db_name/db_user missing, and ENABLE_DATABASE_FAILSAFE=false. Also triggered in tests that disable the failsafe to assert DB configuration is present.

Common situations: Promoting an app to production without provisioning DATABASE_URL; setting DB_USER but forgetting DB_NAME (the triple requires all three); security hardening that sets enable_database_failsafe=false per policy; staging environments that set ENVIRONMENT=production without a DB service; helm charts that gate DATABASE_URL behind an unset secret.

Related errors


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/ad02578b6074ae24. Report an issue: GitHub.