odysseus-dev/odysseus · error · HTTPException

Invalid request parameters

Error message

Invalid request parameters

What it means

Generic 400 raised when the request-shaping phase raises ValueError or pydantic ValidationError — i.e. the submitted parameters are well-formed JSON but semantically invalid. The original exception is swallowed, so the 400 text does not say which field failed.

Source

Thrown at routes/chat_routes.py:1105

                _explicit_browser_intent = True
                if chat_mode == "chat":
                    chat_mode = "agent"
                    auto_escalated = True
                    _workspace_agent_intent = False
                    logger.info("chat→agent auto-escalation: contextual browser/form follow-up")
            if not workspace and isinstance(message, str):
                _auto_workspace, _ = _resolve_workspace_from_message_path(request, message)
                if _auto_workspace:
                    workspace = _auto_workspace
                    chat_mode = "agent"
                    auto_escalated = True
                    _workspace_agent_intent = True
                    allow_bash = "true"
                    logger.info("chat→agent auto-escalation: explicit path workspace=%s", workspace)
        except SessionNotFoundError as e:
            raise HTTPException(404, str(e))
        except (ValueError, ValidationError):
            raise HTTPException(400, "Invalid request parameters")

        # ------------------------------------------------------------------ #
        # Privilege gates that must fire BEFORE any LLM work / token spend.
        #   1. allowed_models — reject if session.model isn't in the user's
        #      configured allowlist (empty list = "no restriction").
        #   2. max_messages_per_day — count user-role ChatMessage rows owned
        #      by this user in the last UTC day; 429 if at/over the cap.
        # Admins always have full privileges via get_privileges (returns
        # ADMIN_PRIVILEGES wholesale) so this is a no-op for them.
        _enforce_chat_privileges(request, sess)

        # Ensure session has auth headers
        resolve_session_auth(sess, session, owner=effective_user(request))

        # Check for research_pending BEFORE mode persist overwrites it
        do_research = str(use_research).lower() == "true"
        if not do_research:
            if get_session_mode(session) == 'research_pending':

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Check server logs/stderr — the swallowed ValueError/ValidationError details are logged or traceable there; the response body alone won't say
  2. Diff the payload against the current request schema (chat_mode, preset_id, attachments, flags) and fix the offending field
  3. After a backend upgrade, refresh the client so option names/types match the new schema
Defensive patterns

Strategy: try-catch

Validate before calling

const ALLOWED_MODES = new Set(['chat','agent','research']);
if (chat_mode && !ALLOWED_MODES.has(chat_mode)) { fixMode(); return; }

Type guard

function isValidChatOptions(o: any): boolean {
  return (!o.chat_mode || ['chat','agent','research'].includes(o.chat_mode))
      && (!o.preset_id || typeof o.preset_id === 'string');
}

Try / catch

try { await streamChat(...); } catch (e) { if (e.status === 400 && e.message === 'Invalid request parameters') { logPayloadForSchemaDiff(payload); } }

Prevention

When it happens

Trigger: POST /api/chat_stream with out-of-range or wrongly-typed options: invalid chat_mode, bad preset_id, malformed attachments metadata, or any enum/constraint pydantic rejects during coercion.

Common situations: Frontend updated to send new option values the backend schema doesn't accept; version skew between client and server after a deploy; hand-written payloads with wrong types (strings for booleans, etc.).

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/247e7572b4c49efe. Report an issue: GitHub.