From e0dbbaec828bad3364e42697565a0aff816e0806 Mon Sep 17 00:00:00 2001 From: Rod Boev Date: Sun, 14 Jun 2026 13:21:32 -0400 Subject: [PATCH] Materialize CLI/TUI sessions before regenerating title (#4183) --- api/routes.py | 5 ++- .../test_issue4183_regenerate_materialize.py | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/test_issue4183_regenerate_materialize.py diff --git a/api/routes.py b/api/routes.py index cc6d860d..c7d4a8bb 100644 --- a/api/routes.py +++ b/api/routes.py @@ -7750,11 +7750,10 @@ def handle_post(handler, parsed) -> bool: sid = body["session_id"] prefer_latest = bool(body.get("prefer_latest", False)) try: - s = get_session(sid) - s = _ensure_full_session_before_mutation(sid, s) + s = _get_or_materialize_session(sid) except KeyError: return bad(handler, "Session not found", 404) - if getattr(s, "read_only", False): + except PermissionError: return bad(handler, "Read-only imported sessions cannot be renamed", 403) next_title, reason, raw_preview = generate_session_title_for_session(s, prefer_latest=prefer_latest) if not next_title: diff --git a/tests/test_issue4183_regenerate_materialize.py b/tests/test_issue4183_regenerate_materialize.py new file mode 100644 index 00000000..fd5da224 --- /dev/null +++ b/tests/test_issue4183_regenerate_materialize.py @@ -0,0 +1,35 @@ +"""Issue #4183: regenerate-title must materialize CLI/TUI sessions from state.db. + +The /api/session/title/regenerate endpoint must use _get_or_materialize_session +so sessions that only exist in state.db (no sidecar JSON) can have their titles +regenerated instead of returning "Session not found". +""" + +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +ROUTES_PY = (ROOT / "api" / "routes.py").read_text(encoding="utf-8") + + +def test_regenerate_endpoint_uses_materialize_fallback(): + start = ROUTES_PY.index('"/api/session/title/regenerate"') + end = ROUTES_PY.index('"/api/personality/set"', start) + block = ROUTES_PY[start:end] + assert "_get_or_materialize_session(sid)" in block, ( + "regenerate handler must use _get_or_materialize_session to find " + "sessions that only exist in state.db (CLI/TUI sessions)" + ) + assert "get_session(sid)" not in block, ( + "regenerate handler must not use bare get_session — it misses " + "CLI/TUI sessions that lack a sidecar JSON file" + ) + + +def test_regenerate_endpoint_catches_permission_error(): + start = ROUTES_PY.index('"/api/session/title/regenerate"') + end = ROUTES_PY.index('"/api/personality/set"', start) + block = ROUTES_PY[start:end] + assert "except PermissionError:" in block, ( + "regenerate handler must catch PermissionError from " + "_get_or_materialize_session for read-only imported sessions" + )