Skip to content

dotenv support is failing for an optional complex type in settings with prefix #568

Closed
@smcoll

Description

@smcoll

Given a .env file which includes an environment variable without a prefixed namespace, but the settings config is configured to use a prefix, it attempts to load the non-prefixed value, then fails to interpret the JSON structure anyway, saying the input type is a string:

1 validation error for Settings
my_model
  Input should be a valid dictionary or instance of MyModel [type=model_type, input_value='{"a":1}', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/model_type

I would expect in this case that it would simply resolve to None - the non-prefixed env variable should be ignored.

Using pydantic-settings 2.8.1 on Python 3.10

To reproduce:

# env-no-prefix.env
MY_MODEL={"a":1}
# env-prefix-and-no-prefix.env
MY_MODEL={"a":2}
PREFIX_MY_MODEL={"a":3}
# env-prefix-only.env
PREFIX_MY_MODEL={"a":4}
# app.py

import pydantic_settings
from pydantic import BaseModel, ConfigDict
from typing import Optional


class MyModel(BaseModel):
    a: int


class Settings(pydantic_settings.BaseSettings):

    model_config = ConfigDict(extra="ignore")

    my_model: Optional[MyModel] = None


for env_file in [
    None,
    "env-no-prefix.env",
    "env-prefix-only.env",
    "env-prefix-and-no-prefix.env",
]:
    for env_prefix in [None, "PREFIX_"]:
        try:
            print(
                f"env_file={env_file}, env_prefix={env_prefix}, settings={Settings(_env_file=env_file, _env_prefix=env_prefix)}",
            )
        except Exception as e:
            print(f"env_file={env_file}, env_prefix={env_prefix}, {e}")

Only one scenario in the env_file/env_prefix matrix is misbehaving (env_file="env-no-prefix.env", env_prefix="PREFIX_") - the others are working as expected:

$ python -m app
env_file=None, env_prefix=None, settings=my_model=None
env_file=None, env_prefix=PREFIX_, settings=my_model=None
env_file=env-no-prefix.env, env_prefix=None, settings=my_model=MyModel(a=1)
env_file=env-no-prefix.env, env_prefix=PREFIX_, 1 validation error for Settings
my_model
  Input should be a valid dictionary or instance of MyModel [type=model_type, input_value='{"a":1}', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/model_type
env_file=env-prefix-only.env, env_prefix=None, settings=my_model=None
env_file=env-prefix-only.env, env_prefix=PREFIX_, settings=my_model=MyModel(a=4)
env_file=env-prefix-and-no-prefix.env, env_prefix=None, settings=my_model=MyModel(a=2)
env_file=env-prefix-and-no-prefix.env, env_prefix=PREFIX_, settings=my_model=MyModel(a=3)

Seems related to #441 but more specific, since it has to do with interpreting a complex type.

Similar to #196

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions