microsoft/semantic-kernel · warning · HTTPException
Missing state parameter
Error message
Missing state parameter
What it means
Raised as HTTPException(400) by SimpleAuthProvider.get_login_page when the state argument is falsy (empty string or None). The provider generates the login form HTML keyed to state; an empty state cannot be associated with the pending authorization, so it refuses to render.
Source
Thrown at python/samples/demos/mcp_with_oauth/server/mcp_simple_auth/simple_auth_provider.py:100
# Store state mapping for callback
self.state_mapping[state] = {
"redirect_uri": str(params.redirect_uri),
"code_challenge": params.code_challenge,
"redirect_uri_provided_explicitly": str(params.redirect_uri_provided_explicitly),
"client_id": client.client_id,
"resource": params.resource, # RFC 8707
}
# Build simple login URL that points to login page
auth_url = f"{self.auth_callback_url}?state={state}&client_id={client.client_id}"
return auth_url
async def get_login_page(self, state: str) -> HTMLResponse:
"""Generate login page HTML for the given state."""
if not state:
raise HTTPException(400, "Missing state parameter")
# Create simple login form HTML
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<title>MCP Demo Authentication</title>
<style>
body {{ font-family: Arial, sans-serif; max-width: 500px; margin: 0 auto; padding: 20px; }}
.form-group {{ margin-bottom: 15px; }}
input {{ width: 100%; padding: 8px; margin-top: 5px; }}
button {{ background-color: #4CAF50; color: white; padding: 10px 15px; border: none; cursor: pointer; }}
</style>
</head>
<body>
<h2>MCP Demo Authentication</h2>
<p>This is a simplified authentication demo. Use the demo credentials below:</p>
<p><strong>Username:</strong> demo_user<br>View on GitHub (pinned to c028a0c7dc)
Solutions
- Ensure callers (login_page_handler) pass a non-empty state to get_login_page.
- Validate state at the HTTP boundary before reaching get_login_page (the route handlers already do this — confirm they are on the call path).
- Generate and persist state during the authorize step so it is always present.
- Return a user-facing error page instead of raising for known-empty state if appropriate.
Example fix
// before
await oauth_provider.get_login_page(state='')
// after
state = request.query_params.get('state')
if not state:
raise HTTPException(400, 'Missing state parameter')
await oauth_provider.get_login_page(state=state) Defensive patterns
Strategy: validation
Validate before calling
if not state:
raise HTTPException(400, 'Missing state parameter')
await oauth_provider.get_login_page(state) Type guard
def is_non_empty_state(state) -> bool:
return isinstance(state, str) and bool(state.strip()) Prevention
- Validate state at the HTTP route before calling get_login_page.
- Generate and persist state during authorize.
- Add unit tests asserting get_login_page rejects empty state.
When it happens
Trigger: get_login_page('') or get_login_page(None); the upstream handler passed an empty/missing state; state was coerced to empty during URL parsing.
Common situations: A handler that does not check state before calling get_login_page; URL parsing edge cases producing empty state; tests invoking get_login_page without state.
Related errors
- Missing state parameter
- Missing state parameter
- Missing username, password, or state parameter
- Invalid parameter types
- OAuth error: {self.callback_data['error']}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/45443943dd1208cb.
Report an issue: GitHub.