Repository: PriorLabs/TabPFN

Issue:
Unrelated environment variables in `.env` file cause validation error
### Describe the bug

I am using TabPFN through AutoGluon, so I am very unfamiliar with this library at the moment, but I have ran into an issue where TabPFN fails to run because I have a `.env` file with variables unrelated to TabPFN. I narrowed it down to `pydantic_settings` defaulting to `extra="forbid"` instead of `extra="ignore"`.

Locally, changing this line allowed TabPFN to run normally:

https://github.com/PriorLabs/TabPFN/blob/0ef6e485880fab72912da5d0286f834378943fb2/src/tabpfn/settings.py#L19

```diff
--- before.py   2025-08-08 20:40:14.799563161 -0600
+++ after.py    2025-08-08 20:39:30.219760231 -0600
@@ -16,7 +16,7 @@
     Prefixed by ``TABPFN_`` in environment variables.
     """
 
-    model_config = SettingsConfigDict(env_prefix="TABPFN_", env_file=".env")
+    model_config = SettingsConfigDict(env_prefix="TABPFN_", env_file=".env", extra="ignore")
 
     # Model Configuration
     model_cache_dir: Path | None = Field(
```

### Steps/Code to Reproduce

As explained above, I am not running TabPFN directly. I am running AutoGluon with GPU support enabled, like this:

```py
from autogluon.tabular import TabularPredictor

predictor = TabularPredictor(label="my-label", path="models").fit(
    "data/train.csv",
    time_limit=120,
    presets=["extreme_quality"],
    num_gpus=1,
    num_bag_folds=5,
    num_bag_sets=1,
    use_bag_holdout=True,
)
```

And, near the start of the run, TabPFN is loaded and ran.

### Expected Results

TabPFN runs normally according to the settings selected by AutoGluon.

### Actual Results

TabPFN fails to run as a result of Pydantic validation errors. Here is an example of an error, with sensitive data omitted:

```
Fitting model: TabPFNv2_r143_BAG_L1 ... Training model for up to 119.98s of the 119.98s of remaining time.
        Fitting 5 child models (S1F1 - S1F5) | Fitting with SequentialLocalFoldFittingStrategy (sequential: cpus=16, gpus=1)
        Warning: Exception caused TabPFNv2_r143_BAG_L1 to fail during training... Skipping this model.
                5 validation errors for TabPFNSettings
db_url
  Extra inputs are not permitted [type=extra_forbidden, input_value='<omitted>', input_type=str]
    For further information visit https://errors.pydantic.dev/2.11/v/extra_forbidden
electricity_usage_directory
  Extra inputs are not permitted [type=extra_forbidden, input_value='<omitted>', input_type=str]
    For further information visit https://errors.pydantic.dev/2.11/v/extra_forbidden
home_assistant_backup_directory
  Extra inputs are not permitted [type=extra_forbidden, input_value='<omitted>', input_type=str]
    For further information visit https://errors.pydantic.dev/2.11/v/extra_forbidden
home_assistant_backup_password
  Extra inputs are not permitted [type=extra_forbidden, input_value='<omitted>', input_type=str]
    For further information visit https://errors.pydantic.dev/2.11/v/extra_forbidden
log_level
  Extra inputs are not permitted [type=extra_forbidden, input_value='<omitted>', input_type=str]
    For further information visit https://errors.pydantic.dev/2.11/v/extra_forbidden
Detailed Traceback:
Traceback (most recent call last):
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/tabular/trainer/abstract_trainer.py", line 2171, in _train_and_save
    model = self._train_single(**model_fit_kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/tabular/trainer/abstract_trainer.py", line 2055, in _train_single
    model = model.fit(X=X, y=y, X_val=X_val, y_val=y_val, X_test=X_test, y_test=y_test, total_resources=total_resources, **model_fit_kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/abstract/abstract_model.py", line 1068, in fit
    out = self._fit(**kwargs)
          ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/ensemble/stacker_ensemble_model.py", line 270, in _fit
    return super()._fit(X=X, y=y, time_limit=time_limit, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/ensemble/bagged_ensemble_model.py", line 389, in _fit
    self._fit_folds(
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/ensemble/bagged_ensemble_model.py", line 868, in _fit_folds
    fold_fitting_strategy.after_all_folds_scheduled()
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/ensemble/fold_fitting_strategy.py", line 350, in after_all_folds_scheduled
    self._fit_fold_model(job)
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/ensemble/fold_fitting_strategy.py", line 355, in _fit_fold_model
    fold_model = self._fit(self.model_base, time_start_fold, time_limit_fold, fold_ctx, self.model_base_kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/ensemble/fold_fitting_strategy.py", line 391, in _fit
    fold_model.fit(X=X_fold, y=y_fold, X_val=X_val_fold, y_val=y_val_fold, time_limit=time_limit_fold, num_cpus=num_cpus, num_gpus=num_gpus, **kwargs_fold)
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/core/models/abstract/abstract_model.py", line 1068, in fit
    out = self._fit(**kwargs)
          ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/autogluon/tabular/models/tabpfnv2/tabpfnv2_model.py", line 170, in _fit
    from tabpfn.model import preprocessing
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/__init__.py", line 3, in <module>
    from tabpfn.classifier import TabPFNClassifier
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/classifier.py", line 34, in <module>
    from tabpfn.base import (
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/base.py", line 13, in <module>
    from tabpfn.architectures.base.bar_distribution import FullSupportBarDistribution
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/architectures/__init__.py", line 14, in <module>
    from . import base
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/architectures/base/__init__.py", line 25, in <module>
    from tabpfn.architectures.base.transformer import PerFeatureTransformer
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/architectures/base/transformer.py", line 24, in <module>
    from tabpfn.architectures.base.layer import PerFeatureEncoderLayer
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/architectures/base/layer.py", line 15, in <module>
    from tabpfn.architectures.base.attention.full_attention import MultiHeadAttention
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/architectures/base/attention/full_attention.py", line 15, in <module>
    from tabpfn.architectures.base.memory import support_save_peak_mem_factor
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/architectures/base/memory.py", line 14, in <module>
    from tabpfn.settings import settings
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/tabpfn/settings.py", line 70, in <module>
    settings = Settings()
               ^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/pydantic_settings/main.py", line 188, in __init__
    super().__init__(
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/pydantic/main.py", line 253, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/pydantic_settings/main.py", line 188, in __init__
    super().__init__(
  File "/home/vscode/.cache/uv-env/lib/python3.12/site-packages/pydantic/main.py", line 253, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

### Versions

```shell
Collecting system and dependency information...
PyTorch version: 2.7.1+cu126
CUDA used to build PyTorch: 12.6
ROCM used to build PyTorch: N/A

OS: Debian GNU/Linux 11 (bullseye) (x86_64)
GCC version: (Debian 10.2.1-6) 10.2.1 20210110
Clang version: Could not collect
CMake version: Could not collect
Libc version: glibc-2.31

Python version: 3.12.11 (main, Jul  1 2025, 05:28:02) [GCC 10.2.1 20210110] (64-bit runtime)
Python platform: Linux-5.15.167.4-microsoft-standard-WSL2-x86_64-with-glibc2.31
Is CUDA available: True
CUDA runtime version: Could not collect
CUDA_MODULE_LOADING set to: LAZY
GPU models and configuration: GPU 0: NVIDIA GeForce RTX 4070 Ti SUPER
Nvidia driver version: 576.80
cuDNN version: Could not collect
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True

CPU:
Architecture:                         x86_64
CPU op-mode(s):                       32-bit, 64-bit
Byte Order:                           Little Endian
Address sizes:                        39 bits physical, 48 bits virtual
CPU(s):                               32
On-line CPU(s) list:                  0-31
Thread(s) per core:                   2
Core(s) per socket:                   16
Socket(s):                            1
Vendor ID:                            GenuineIntel
CPU family:                           6
Model:                                183
Model name:                           Intel(R) Core(TM) i9-14900KF
Stepping:                             1
CPU MHz:                              3187.201
BogoMIPS:                             6374.40
Virtualization:                       VT-x
Hypervisor vendor:                    Microsoft
Virtualization type:                  full
L1d cache:                            768 KiB
L1i cache:                            512 KiB
L2 cache:                             32 MiB
L3 cache:                             36 MiB
Vulnerability Gather data sampling:   Not affected
Vulnerability Itlb multihit:          Not affected
Vulnerability L1tf:                   Not affected
Vulnerability Mds:                    Not affected
Vulnerability Meltdown:               Not affected
Vulnerability Mmio stale data:        Not affected
Vulnerability Reg file data sampling: Mitigation; Clear Register File
Vulnerability Retbleed:               Mitigation; Enhanced IBRS
Vulnerability Spec rstack overflow:   Not affected
Vulnerability Spec store bypass:      Mitigation; Speculative Store Bypass disabled via prctl and seccomp
Vulnerability Spectre v1:             Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:             Mitigation; Enhanced / Automatic IBRS; IBPB conditional; RSB filling; PBRSB-eIBRS SW sequence; BHI BHI_DIS_S
Vulnerability Srbds:                  Not affected
Vulnerability Tsx async abort:        Not affected
Flags:                                fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves avx_vnni umip waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm md_clear serialize flush_l1d arch_capabilities

Dependency Versions:
--------------------
tabpfn: 2.1.2
torch: 2.7.1
numpy: 2.1.3
scipy: 1.16.1
pandas: 2.3.1
scikit-learn: 1.6.1
typing_extensions: 4.14.1
einops: 0.8.1
huggingface-hub: 0.34.3
```


Discussion:

Patch:
diff --git a/src/tabpfn/settings.py b/src/tabpfn/settings.py
index c1b4fb25..3585bf15 100644
--- a/src/tabpfn/settings.py
+++ b/src/tabpfn/settings.py
@@ -16,7 +16,11 @@ class TabPFNSettings(BaseSettings):
     Prefixed by ``TABPFN_`` in environment variables.
     """
 
-    model_config = SettingsConfigDict(env_prefix="TABPFN_", env_file=".env")
+    # Set extra="ignore" so that unknown keys in the .env file, for example, entries for
+    # other applications, do not cause validation errors.
+    model_config = SettingsConfigDict(
+        env_prefix="TABPFN_", env_file=".env", extra="ignore"
+    )
 
     # Model Configuration
     model_cache_dir: Path | None = Field(


Test patch:
diff --git a/tests/test_settings.py b/tests/test_settings.py
new file mode 100644
index 00000000..da3e8f34
--- /dev/null
+++ b/tests/test_settings.py
@@ -0,0 +1,16 @@
+from __future__ import annotations
+
+from pathlib import Path
+
+from tabpfn.settings import TabPFNSettings
+
+
+def test__load_settings__env_file_contains_variables_for_other_apps__does_not_crash(
+    tmp_path: Path,
+) -> None:
+    env_file = tmp_path / ".env"
+    with env_file.open(mode="w") as f:
+        f.write("OTHER_APP_VAR=1\n")
+        f.write("TABPFN_MODEL_CACHE_DIR=test_cache_dir\n")
+    tabpfn_settings = TabPFNSettings(_env_file=env_file)
+    assert str(tabpfn_settings.model_cache_dir) == "test_cache_dir"