A list column backfilled with a dictionary
Reported as a 500 on a live instance, immediately after it updated, and read
off its journal rather than guessed at:
ValueError: Attribute 'reasoning_efforts' does not accept objects of
type <class 'dict'>
`Mapped[list[str]]` is not Optional, so the column is NOT NULL, so SQLite
demands a default for the rows that already exist. `_literal_default` chose one
by asking `column.type.python_type` -- and `MutableList.as_mutable(JSON)`
returns the *same* JSON type object with a listener attached rather than
subclassing it, so `python_type` is `dict` for both flavours. Every existing row
got '{}' in a list column, and MutableList refuses a dict while *loading*: not a
wrong value sitting quietly, an exception on every read of the table.
Model.reasoning_efforts was the first list-shaped JSON column this project had
ever added to a table that already had rows, so the flaw had been harmless since
the runner was written. 1.2.0 stepped on it.
The shape now comes from the column's Python-side default -- `default=list`
against `default=dict` -- which is the only thing that can tell the two apart.
And `repair_json_shapes` puts right what was already written, on start,
converging like ensure_fts beside it, narrow enough that a legitimate {} in a
dict column survives.
Why 1981 tests missed it: conftest builds a fresh database, where the column is
created from the model with its real default. The backfill only runs on a
database that already exists, so the suite had never once exercised the path
that broke. The new tests corrupt a row exactly as the migration did and assert
it loads again.
Verified against a backup of the reporting instance's own database: the load
raises before, eleven rows are repaired, all eleven models load after.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,23 @@ for 1.0.0 have something to be assembled from.
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 1.3.1
|
||||
|
||||
- Fixed: **updating to 1.2.0 or later broke every page that lists models**, with
|
||||
a 500 and nothing but the error page to show for it. The per-model reasoning
|
||||
effort list added in 1.2.0 was the first list-shaped setting this application
|
||||
had ever added to a table that already had rows in it, and the code that fills
|
||||
in such a column on existing rows could not tell a list from a dictionary — so
|
||||
it wrote the wrong kind of empty value into every model, and reading one back
|
||||
raised rather than returning nothing.
|
||||
|
||||
A fresh install was never affected, which is exactly why it was not caught:
|
||||
the column is only filled in that way on a database that already existed.
|
||||
|
||||
This release both stops it happening and **puts right the rows already
|
||||
written**, on start, with nothing to run by hand. If your instance is showing
|
||||
the error page, updating is the whole fix.
|
||||
|
||||
## 1.3.0
|
||||
|
||||
- **A model's reasoning efforts can now be detected rather than known.** There
|
||||
|
||||
Reference in New Issue
Block a user