odysseus-dev/odysseus · error · HTTPException
Assistant not available
Error message
Assistant not available
What it means
Raised by GET /api/assistant/settings when _get_or_create(owner) returns None. That helper looks up the CrewMember flagged is_default_assistant for the owner, and if absent calls task_scheduler.ensure_assistant_defaults then re-queries; None means both the lookup and the post-seed re-query found nothing, i.e. the lazy seed failed without raising.
Source
Thrown at routes/assistant_routes.py:141
async def get_assistant_session(request: Request):
"""Resolve (or lazily create) the pinned Assistant session for this user."""
owner = _owner(request)
crew = await _get_or_create(owner)
if not crew or not crew.session_id:
raise HTTPException(status_code=500, detail="Assistant session could not be resolved")
return {
"session_id": crew.session_id,
"crew_member_id": crew.id,
"name": crew.name,
}
@router.get("/settings")
async def get_assistant_settings(request: Request):
"""Return CrewMember fields + the three check-in task rows + task IDs for logs."""
owner = _owner(request)
crew = await _get_or_create(owner)
if not crew:
raise HTTPException(status_code=500, detail="Assistant not available")
db = SessionLocal()
try:
tasks = db.query(ScheduledTask).filter(
ScheduledTask.owner == owner,
ScheduledTask.crew_member_id == crew.id,
).order_by(ScheduledTask.scheduled_time.asc()).all()
return {
"crew": _crew_to_dict(crew),
"check_ins": [_task_to_checkin_dict(t) for t in tasks],
"task_ids": [t.id for t in tasks],
}
finally:
db.close()
@router.patch("/settings")
async def update_assistant_settings(payload: AssistantSettingsUpdate, request: Request):
"""Update CrewMember fields and/or check-in tasks in one call."""
owner = _owner(request)View on GitHub (pinned to f9235ebbf1)
Solutions
- Retry the request once (lazy seeding is idempotent) — transient DB locks during first seed are the most common cause.
- Check server logs for exceptions from task_scheduler.ensure_assistant_defaults for this owner.
- Verify the crew_members table exists and has the is_default_assistant column populated (schema current after upgrades).
- If the row keeps disappearing, look for a concurrent cleanup/admin-wipe job deleting it between seed and read.
Defensive patterns
Strategy: retry
Validate before calling
const s = await fetch('/api/auth/status', {credentials: 'include'});
if (!s.ok) throw new Error('not authenticated'); // fix auth before expecting assistant data Try / catch
try {
const r = await fetch('/api/assistant/settings', {credentials: 'include'});
if (r.status === 500 && (await r.json()).detail === 'Assistant not available') {
await new Promise(res => setTimeout(res, 1500));
return (await fetch('/api/assistant/settings', {credentials: 'include'})).json();
}
if (!r.ok) throw new Error(`assistant settings failed: ${r.status}`);
return r.json();
} catch (e) { throw e; } Prevention
- Hit GET /api/assistant/session once after login to force seeding before rendering settings.
- Avoid admin-wipe or user-deletion jobs racing active user sessions.
- Keep the SQLite file on a filesystem that supports locking; 'database is locked' during seed is the usual root cause.
When it happens
Trigger: First authenticated GET /api/assistant/settings for a user when ensure_assistant_defaults raises internally (DB locked/corrupt) or returns without committing the CrewMember row; the crew row was deleted (admin wipe) and reseeding is broken; RESERVED_USERNAMES check passed but the seed path is short-circuited.
Common situations: Admin-wipe or user-deletion flows that removed crew_members rows while the app's seeding code path had an error; SQLite 'database is locked' during the seed transaction; restored/partial database missing the crew_members table contents.
Related errors
- Assistant session could not be resolved
- Assistant not found
- Failed to delete calendar
- Failed to list calendars
- Failed to create calendar
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/a45437b02d8dfcd7.
Report an issue: GitHub.