Tencent/WeKnora · error

engine ID is required for Google provider

Error message

engine ID is required for Google provider

What it means

NewGoogleProvider requires a non-empty EngineID (the Programmable Search/Custom Search Engine ID, cx) and returns this error when it is missing. Like the API key, the engine ID comes only from parameters — there is no environment fallback.

Source

Thrown at internal/infrastructure/web_search/google.go:30

	"github.com/Tencent/WeKnora/internal/types"
	"github.com/Tencent/WeKnora/internal/types/interfaces"
)

// GoogleProvider implements web search using Google Custom Search Engine API
type GoogleProvider struct {
	srv      *customsearch.Service
	apiKey   string
	engineID string
}

// NewGoogleProvider creates a new Google provider from parameters (no environment variables).
// The API endpoint is the official Google Custom Search endpoint — not tenant-configurable.
func NewGoogleProvider(params types.WebSearchProviderParameters) (interfaces.WebSearchProvider, error) {
	if params.APIKey == "" {
		return nil, fmt.Errorf("API key is required for Google provider")
	}
	if params.EngineID == "" {
		return nil, fmt.Errorf("engine ID is required for Google provider")
	}

	httpClient, err := NewSearchHTTPClient(30*time.Second, params.ProxyURL)
	if err != nil {
		return nil, err
	}
	clientOpts := []option.ClientOption{
		option.WithAPIKey(params.APIKey),
		option.WithHTTPClient(httpClient),
	}
	srv, err := customsearch.NewService(context.Background(), clientOpts...)
	if err != nil {
		return nil, err
	}
	return &GoogleProvider{
		srv:      srv,
		apiKey:   params.APIKey,
		engineID: params.EngineID,

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set params.EngineID to the cx value from your Programmable Search Engine settings.
  2. Create a Programmable Search Engine at programmablesearchengine.google.com if none exists and copy its ID.
  3. Ensure the config loader maps the engine ID field into WebSearchProviderParameters.

Example fix

// before
provider, err := NewGoogleProvider(types.WebSearchProviderParameters{APIKey: apiKey})
// after
provider, err := NewGoogleProvider(types.WebSearchProviderParameters{APIKey: apiKey, EngineID: cfg.GoogleEngineID})
Defensive patterns

Strategy: validation

Validate before calling

if params.EngineID == "" {
    return errors.New("google search provider requires EngineID (cx) — check config")
}
provider, err := NewGoogleProvider(params)

Try / catch

provider, err := NewGoogleProvider(params)
if err != nil {
    return nil, fmt.Errorf("init google search provider: %w", err)
}

Prevention

When it happens

Trigger: Calling NewGoogleProvider with params.APIKey set but params.EngineID == "".

Common situations: Developer set the API key but forgot the Programmable Search Engine ID; config schema has no field for engine ID; created an API key but never created/configured the search engine in Google's control panel.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


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