From d5043100a7bc28ba02a49323e4a927b39f88d779 Mon Sep 17 00:00:00 2001 From: Chaim Date: Sun, 10 May 2026 18:54:44 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20json.loads=20JSONB=20overrides=20on=20GE?= =?UTF-8?q?T=20=E2=80=94=20asyncpg=20has=20no=20codec=20registered?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit asyncpg returns JSONB columns as raw JSON strings when no type codec is configured (only pgvector is registered in _init_connection). The stored value is a correct JSONB array (jsonb_typeof=array confirmed), but asyncpg decodes it as str. Parse it explicitly in the GET handler so the frontend receives the correct Python list/dict. Co-Authored-By: Claude Sonnet 4.6 --- web/app.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/app.py b/web/app.py index 1294139..cb58178 100644 --- a/web/app.py +++ b/web/app.py @@ -3057,8 +3057,16 @@ async def api_get_methodology(category: str): items = {} for key, default_val in defaults.items(): if key in overrides: + raw = overrides[key]["rule_value"] + # asyncpg returns JSONB as a raw JSON string when no codec is registered. + # Parse it back to a Python object so the frontend receives the correct type. + if isinstance(raw, str): + try: + raw = json.loads(raw) + except (json.JSONDecodeError, TypeError): + pass items[key] = { - "value": overrides[key]["rule_value"], + "value": raw, "is_override": True, "updated_at": overrides[key]["created_at"].isoformat() if overrides[key]["created_at"] else None, }