Skip to content

RedisBackendConfig(redis_url=...) raises extra_forbidden whenever REDIS_URL env is set #225

Description

@27Bslash6

Found while fixing #222 (PR #224 — its CI run tripped over this).

Repro

With REDIS_URL (or CACHEKIT_REDIS_URL) set in the environment — as it is in CI and most deployments:

>>> import os; os.environ["REDIS_URL"] = "redis://localhost:6379"
>>> from cachekit.backends.redis.config import RedisBackendConfig
>>> RedisBackendConfig(redis_url="redis://cfg-host:7000")
pydantic_core._pydantic_core.ValidationError: 1 validation error for RedisBackendConfig
redis_url
  Extra inputs are not permitted [type=extra_forbidden, input_value='redis://cfg-host:7000', input_type=str]

Without the env var set, the same call works.

Why

redis_url has validation_alias=AliasChoices("CACHEKIT_REDIS_URL", "REDIS_URL"). When the env source supplies a value, it enters the merged input keyed by the alias; the field is then populated via the alias, and the redis_url constructor kwarg is left unconsumed — which extra="forbid" rejects. populate_by_name=True only helps when no alias key is present.

Impact

  • The documented "Configuration via Python" example (docs/backends/redis.md) cannot be constructed in any environment that has REDIS_URL set — i.e. exactly the environments where you'd want to override it explicitly.
  • tests/performance/test_file_backend_perf.py constructs this config inside a try/except and silently skips when it blows up.
  • Doctests in RedisBackendConfig pass only because the doctest environment doesn't set the env vars.

Constraints on a fix

Naively adding "redis_url" to the AliasChoices interacts badly with case_sensitive=False — the field-name alias would match the REDIS_URL env var case-insensitively and could invert the documented CACHEKIT_REDIS_URL > REDIS_URL priority. Likely needs either a mode="before" validator that reconciles the alias/name keys (init value must win — matching #222's "explicit argument wins" principle) or a rethink of how the env aliases are attached. Same pattern applies to any future field given a validation_alias.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions