Skip to content

Commit 9202dc4

Browse files
committed
Fix dump_config when a model field is None (e.g. fallback_model)
VibeConfig.dump_config used to call tomli_w.dump on the raw dict returned by model_dump(); tomli_w cannot serialize Python None. Pydantic's to_jsonable_python(exclude_none=True) only drops Nones from Pydantic models, not from plain dicts. Add a recursive _strip_none helper used by dump_config so any Optional[...] field with a None default round-trips through the TOML file cleanly. Triggered by the new ModelConfig.fallback_model: str | None field which broke 21 tests under tests/acp/ that round-trip a config.
1 parent 0a8c815 commit 9202dc4

1 file changed

Lines changed: 19 additions & 1 deletion

File tree

‎albert_code/core/config.py‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,18 @@ def _default_alias_to_name(cls, data: Any) -> Any:
341341
]
342342

343343

344+
def _strip_none(value: Any) -> Any:
345+
"""Return a copy of `value` with all None values removed, recursively.
346+
347+
Used before TOML serialization, since tomli_w refuses None.
348+
"""
349+
if isinstance(value, dict):
350+
return {k: _strip_none(v) for k, v in value.items() if v is not None}
351+
if isinstance(value, list):
352+
return [_strip_none(v) for v in value if v is not None]
353+
return value
354+
355+
344356
class VibeConfig(BaseSettings):
345357
active_model: str = "albert-code"
346358
vim_keybindings: bool = False
@@ -635,8 +647,14 @@ def deep_merge(target: dict, source: dict) -> None:
635647

636648
@classmethod
637649
def dump_config(cls, config: dict[str, Any]) -> None:
650+
# tomli_w cannot serialize Python None values, and Pydantic's
651+
# `to_jsonable_python(exclude_none=True)` only drops Nones from
652+
# Pydantic models, not from plain dicts that have already been
653+
# produced via `model_dump()`. Strip them recursively here so that
654+
# any Optional[...] field with a None default round-trips cleanly.
655+
cleaned = _strip_none(to_jsonable_python(config, fallback=str))
638656
with CONFIG_FILE.path.open("wb") as f:
639-
tomli_w.dump(config, f)
657+
tomli_w.dump(cleaned, f)
640658

641659
@classmethod
642660
def _migrate(cls) -> None:

0 commit comments

Comments
 (0)