やりたいこと
pydantic-settings を使って環境変数を型安全に管理している。
validation_alias で環境変数名(大文字)とフィールド名(スネークケース)をマッピングしている。
# 概念コード — 本番実装とは異なります
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env")
llm_model: str = Field(
default="gpt-4.1-nano",
validation_alias="LLM_MODEL", # 環境変数名をエイリアスで指定
)
依存パッケージを更新したら、これを使ったテスト12件が一斉に落ちた。
環境
| パッケージ | バージョン |
|---|---|
| Python | 3.12 |
| pydantic-settings | 2.7.1(ここが原因) |
| pydantic | 2.x |
| FastAPI | 0.115.x |
エラー内容
FAILED test_settings.py::test_default_model - ValidationError: Extra inputs are not permitted
FAILED test_settings.py::test_custom_model - ValidationError: Extra inputs are not permitted
... (12件)
テストコードはこのような形:
# 概念コード — 本番実装とは異なります
def test_custom_model():
settings = Settings(LLM_MODEL="gpt-4.1-nano") # ← ここでエラー
assert settings.llm_model == "gpt-4.1-nano"
原因
pydantic-settings 2.7.1 からデフォルト挙動が変更された。
| バージョン |
extra のデフォルト |
|---|---|
| 2.7.0 以前 |
'ignore'(未定義フィールドは無視) |
| 2.7.1 以降 | 'forbid'(未定義フィールドはエラー) |
validation_alias を使っている場合、この変更が罠になる。
なぜ罠になるか
フィールド名は llm_model(スネークケース)だが、validation_alias="LLM_MODEL" を指定している。
extra='forbid' が有効になると、Pydantic は フィールド名のチェックを先に行う。
入力キー LLM_MODEL はフィールド名 llm_model と一致しないため、validation_alias で解決される前に弾かれる。
# 2.7.1 以降の内部処理イメージ
入力: LLM_MODEL="gpt-4.1-nano"
→ フィールド名チェック: "LLM_MODEL" == "llm_model" ? NO
→ extra='forbid' → ValidationError: Extra inputs are not permitted
※ validation_alias での解決は行われない
修正
SettingsConfigDict に extra="ignore" を1行追加するだけ。
# 概念コード — 本番実装とは異なります
# OK: extra="ignore" を明示する
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
extra="ignore", # ← これだけ。2.7.0 以前の挙動に戻す
)
llm_model: str = Field(
default="gpt-4.1-nano",
validation_alias="LLM_MODEL",
)
# テストも通るようになる
settings = Settings(LLM_MODEL="gpt-4.1-nano") # OK
assert settings.llm_model == "gpt-4.1-nano" # OK
ハマりポイント
- エラーメッセージ
Extra inputs are not permittedだけでは、pydantic-settingsのデフォルト変更が原因とは気づきにくい -
validation_aliasを使っていない場合はこの問題が発生しないため、プロジェクトによって再現しないケースもある -
pydantic-settingsのCHANGELOGを追っていないと発見が遅れる
確認コマンド
# 現在のバージョンを確認
pip show pydantic-settings | grep Version
# 2.7.1 以上なら extra="ignore" の明示を検討する
まとめ
| 項目 | 内容 |
|---|---|
| 影響バージョン | pydantic-settings 2.7.1 以降 |
| 症状 |
validation_alias を使ったテストで ValidationError: Extra inputs are not permitted
|
| 原因 | デフォルトが extra='ignore' → extra='forbid' に変更 |
| 修正 |
SettingsConfigDict(extra="ignore") を1行追加 |
validation_alias でハマったら、まず extra="ignore" を試してみる。
背景・全体ストーリー(LLM移行の文脈でなぜこれを踏んだか)はnoteに → https://note.com/yamashita_aidev/n/n6fb379a97424