Tencent/WeKnora · error

principal context is missing from OAuth state

Error message

principal context is missing from OAuth state

What it means

Fired in CompleteAuthorization when the stored OAuth state carries no usable principal: after Normalize and the UserID fallback, the principal is still invalid. Without knowing which user completed the flow, tokens cannot be attributed, so the callback is rejected. Usually means corrupted/tampered state or a schema change in the state store.

Source

Thrown at internal/mcp/oauth_manager.go:196

// still carries the previous OAuth client registration.
func (m *OAuthManager) CompleteAuthorization(
	ctx context.Context, state, code string,
) (frontendRedirect, serviceID string, err error) {
	ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), oauthCallbackTimeout)
	defer cancel()

	st, err := m.states.Take(ctx, state)
	if err != nil {
		return "", "", err
	}
	frontendRedirect = st.FrontendRedirect
	serviceID = st.ServiceID
	principal := st.Principal.Normalize()
	if !principal.Valid() && st.UserID != "" {
		principal = types.Principal{Type: types.PrincipalWebUser, ID: st.UserID}.Normalize()
	}
	if !principal.Valid() {
		return frontendRedirect, serviceID, fmt.Errorf("principal context is missing from OAuth state")
	}

	service, err := m.serviceRepo.GetByID(ctx, st.TenantID, st.ServiceID)
	if err != nil {
		return frontendRedirect, serviceID, fmt.Errorf("failed to load MCP service: %w", err)
	}
	if service == nil {
		return frontendRedirect, serviceID, fmt.Errorf("MCP service not found")
	}

	h, err := m.newHandler(ctx, service, st.TenantID, principal, st.RedirectURI)
	if err != nil {
		return frontendRedirect, serviceID, err
	}
	// Re-prime the expected state so the library's CSRF check passes after
	// reconstructing the handler in this separate request.
	h.SetExpectedState(state)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check how the state entry was written in StartAuthorization (Principal and UserID fields)
  2. Have the user restart the authorization flow to write fresh state
  3. Audit the state store for corrupted or legacy entries
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/mcp/oauth_manager.go:196 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/819a1f5c43b645c1. Report an issue: GitHub.