vxcontrol/pentagi · error

NotPermitted

NotPermitted

Error message

provider not initialized

What it means

AuthAuthorize looks up the OAuth2 client for the ?provider= query parameter in the server's initialized oauth map; if no client is registered under that name it responds with ErrNotPermitted and 'provider not initialized'. Providers are only registered at startup when their credentials (client ID/secret) are configured, so an unknown or unconfigured provider name fails here before any redirect happens.

Source

Thrown at backend/pkg/server/services/auth.go:273

	}

	queryReturnURI := c.Query("return_uri")
	if queryReturnURI != "" {
		returnURL, err := url.Parse(queryReturnURI)
		if err != nil {
			logger.FromContext(c).WithError(err).Errorf("failed to parse return url argument '%s'", queryReturnURI)
			response.Error(c, response.ErrAuthInvalidAuthorizeQuery, err)
			return
		}
		returnURL.Path = path.Clean(path.Join("/", returnURL.Path))
		stateData["return_uri"] = returnURL.RequestURI()
	}

	provider := c.Query("provider")
	oauthClient, ok := s.oauth[provider]
	if !ok {
		logger.FromContext(c).Errorf("external OAuth2 provider '%s' is not initialized", provider)
		err := fmt.Errorf("provider not initialized")
		response.Error(c, response.ErrNotPermitted, err)
		return
	}
	stateData["provider"] = provider

	stateUniq, err := randBase64String(16)
	if err != nil {
		logger.FromContext(c).WithError(err).Errorf("failed to generate state random data")
		response.Error(c, response.ErrInternal, err)
		return
	}
	stateData["uniq"] = stateUniq

	nonce, err := randBase64String(16)
	if err != nil {
		logger.FromContext(c).WithError(err).Errorf("failed to generate nonce random data")
		response.Error(c, response.ErrInternal, err)
		return

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check the provider query value is exactly an initialized one (e.g. 'google', 'github').
  2. Set the provider's client ID/secret env vars (see pkg/config/config.go) and restart the backend so the client registers.
  3. If using docker-compose, ensure the OAuth env vars are declared in the compose file / .env and actually reach the container.
  4. Log the available provider keys at startup and compare against the incoming value.
  5. Guard the frontend login buttons to only render providers that the backend advertises as enabled.

Example fix

// before
GET /auth/authorize?provider=Google   // case/name mismatch
// after
GET /auth/authorize?provider=google   // exact registered provider key
Defensive patterns

Strategy: validation

Validate before calling

// verify the provider is configured before linking the login button (server exposes enabled providers)
func providerEnabled(cfg *config.Config, name string) bool {
    switch name {
    case "google":
        return cfg.OAuthGoogleClientID != "" && cfg.OAuthGoogleClientSecret != ""
    case "github":
        return cfg.OAuthGithubClientID != "" && cfg.OAuthGithubClientSecret != ""
    }
    return false
}

Type guard

func isKnownProvider(name string) bool {
    return name == "google" || name == "github"
}

Try / catch

_, err := client.Authorize(ctx, "google")
var respErr *response.Error
if errors.As(err, &respErr) && respErr.Code == response.ErrNotPermitted {
    return fmt.Errorf("provider not enabled on this deployment; set its OAUTH client credentials")
}
if err != nil { return err }

Prevention

When it happens

Trigger: GET /auth/authorize?provider=<name> where <name> is misspelled, not one of google/github, or the provider is valid but its env credentials were not set so the client was never constructed at startup.

Common situations: Frontend link with a wrong provider slug; OAUTH_(GOOGLE|GITHUB)_CLIENT_ID/SECRET missing from .env so the provider is disabled; switching provider names after a rename; docker-compose not passing the OAuth env vars through.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/9255640d66ae9565. Report an issue: GitHub.