Skip to content

Commit fd810d1

Browse files
ehsan6shaclaude
andcommitted
routes: phone-context auto-creates session instead of 404
Real-world phone failure observed 2026-05-27: POST /troubleshoot/phone-context HTTP/1.1" 404 Not Found → App shows "[http-not-found] Session not found" Root causes the old 404 didn't handle gracefully: 1. User taps "Share my phone's context" BEFORE the first /troubleshoot call — the app has generated a UUID for the upcoming session and tries to prime it with phone state. The server didn't know about the UUID yet. 2. Container restarted between sessions — the app's cached session_id was valid before restart but the in-memory session map is now empty. App shows scary "Session not found" instead of just resuming. Fix: when phone-context receives an unknown session_id, create the session with that id instead of 404'ing. Idempotent prime-then- troubleshoot — the next /troubleshoot with the same session_id finds the session already there with phone_context attached. The SessionManager.create(session_id=...) path already exists for caller-supplied IDs in /troubleshoot; this just hooks it into phone-context too. Test updated: test_phone_context_unknown_session_returns_404 → test_phone_context_unknown_session_auto_creates. Asserts the session is created with the supplied id AND the phone_context is attached. 244/244 tests still pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 9e1334c commit fd810d1

2 files changed

Lines changed: 48 additions & 6 deletions

File tree

src/routes/troubleshoot.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,35 @@ async def user_reply(req: UserReplyRequest, request: Request) -> Response:
167167
async def phone_context(req: PhoneContextRequest, request: Request) -> Response:
168168
"""Phase 11 contract: in-memory only. Validates body against
169169
phone_context.schema.json (the inner shape). On validation error,
170-
sanitize SSID/BSSID/IP before any log line."""
170+
sanitize SSID/BSSID/IP before any log line.
171+
172+
Auto-creates the session if the supplied session_id doesn't exist
173+
(idempotent prime-then-troubleshoot pattern). This handles two
174+
real-world cases observed in production:
175+
1. User taps "Share my phone's context" BEFORE starting a
176+
/troubleshoot session — the app has generated a UUID and
177+
wants to attach the phone snapshot to it; the next
178+
/troubleshoot with that same session_id will find the
179+
pre-primed session with phone_context already loaded.
180+
2. Container restarted between sessions — the app's cached
181+
session_id was valid before the restart but the in-memory
182+
session map is now empty. Auto-create avoids a confusing
183+
"Session not found" error in the UI; the user gets the same
184+
outcome as starting fresh, just labelled with the existing
185+
session_id.
186+
"""
171187
schemas = request.app.state.schemas
172188
session_mgr = request.app.state.session_manager
173189
session = session_mgr.get(req.session_id)
174190
if session is None:
175-
return JSONResponse(
176-
status_code=404,
177-
content=_error_body("session_not_found"),
191+
# Don't 404 — create the session with the supplied id. Slide
192+
# TTL via touch() at the end so the auto-created session has
193+
# a full 30 min before pruning.
194+
logger.info(
195+
"session_auto_created_via_phone_context session=%s",
196+
req.session_id,
178197
)
198+
session = session_mgr.create(session_id=req.session_id)
179199
pc_validator = schemas.validator_for("phone_context.schema.json")
180200
errors = list(pc_validator.iter_errors(req.phone_context))
181201
if errors:

tests/test_troubleshoot_conversational.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,34 @@ def _good_phone_context() -> dict:
7777
}
7878

7979

80-
def test_phone_context_unknown_session_returns_404(client):
80+
def test_phone_context_unknown_session_auto_creates(client):
81+
"""Behavior change 2026-05-27: phone-context with an unknown
82+
session_id now AUTO-CREATES the session (matches the prime-then-
83+
troubleshoot pattern + survives container restart). Previously
84+
returned 404 with `session_not_found` and the phone app showed
85+
"[http-not-found] Session not found" to the user.
86+
87+
Real-world cases this unblocks:
88+
- User taps "Share my phone's context" before starting
89+
/troubleshoot — the app's pre-generated session_id should
90+
prime the session; the next /troubleshoot with that same
91+
session_id finds the session with phone_context already
92+
attached.
93+
- Container restarted between sessions; the app's cached
94+
session_id is no longer in the in-memory map. Auto-create
95+
avoids a confusing "Session not found" error in the UI.
96+
"""
97+
mgr = client.app.state.session_manager
98+
assert mgr.get("nope") is None
8199
r = client.post("/troubleshoot/phone-context", json={
82100
"session_id": "nope",
83101
"phone_context": _good_phone_context(),
84102
})
85-
assert r.status_code == 404
103+
assert r.status_code == 200
104+
# Session was created with the supplied id + phone_context attached
105+
s = mgr.get("nope")
106+
assert s is not None
107+
assert s.phone_context == _good_phone_context()
86108

87109

88110
def test_phone_context_validates_body_envelope(client):

0 commit comments

Comments
 (0)