Runtime-variant CRUD 400s when default_model_definition is JSON null (regression from #12970)
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 368
Description
## Symptom
After #12970 (BA-6942), all runtime-variant CRUD/search component tests fail with:
```
InvalidRequestError(400, 'Schema validation failed',
'1 validation error for RuntimeVariantModelDefinitionInfo
Input should be a valid dictionary or object to extract fields from
[type=model_attributes_type, input_value=None, input_type=NoneType]')
```
`tests/component/runtime_variant/test_runtime_variant_crud.py` — 6/7 tests fail. Reproduces **deterministically on a clean checkout of current main locally** (`pants test tests/component/runtime_variant/test_runtime_variant_crud.py`), and intermittently on CI (observed twice on an unrelated PR branch, #12979, while other same-base runs passed — the CI-side variance itself is unexplained and worth a look).
## Root cause
`runtime_variants.default_model_definition` is `nullable=False`, but that only forbids **SQL NULL** — a `PydanticColumn` write of Python `None` stores **JSON `null`**, which satisfies the constraint. When a runtime variant is created without a model definition, the row round-trips as `None`, and the adapter introduced in #12970 crashes on it:
```python
# api/adapters/runtime_variant/adapter.py (_data_to_node)
default_model_definition=RuntimeVariantModelDefinitionInfo.model_validate(
data.default_model_definition, # None -> pydantic model_attributes_type error
from_attributes=True,
)
```
`RuntimeVariantData.default_model_definition` is typed non-optional (`ModelDefinitionDraft`), so the None slips through untyped from the row.
## Suggested fix directions
Either (a) make the creation path always materialize a default draft (and backfill existing JSON-null rows via migration), or (b) treat the field as optional end-to-end (`ModelDefinitionDraft | None` on the row/data/DTO and a None-tolerant adapter). (a) matches the intent of "expose model defaults" better.
cc @seedspirit (BA-6942)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
Research direction
Run `pants test tests/component/runtime_variant/test_runtime_variant_crud.py` to reproduce the failure. Read `api/adapters/runtime_variant/adapter.py`, especially `_data_to_node`, then trace the runtime-variant creation path and the row/data/DTO definitions for `default_model_definition`. Done means the CRUD/search component tests pass without JSON-null validation errors, including coverage for variants created without a model definition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend, database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100