siyuan-note/siyuan · error

provider base URL is required

Error message

provider base URL is required

What it means

resolveAIProvider, when given an inline providerConfig, requires a non-blank BaseURL on the provider. After unmarshalling the supplied config into conf.Provider, an empty base URL means no API endpoint is known, so the request is refused before any network call.

Solutions

  1. Set the provider's baseURL to the full API endpoint (e.g. https://api.openai.com) and retry
  2. Check field-name casing in the JSON payload — it must map to conf.Provider's BaseURL tag
  3. If switching from providerID reference to inline config, copy the BaseURL from the existing saved provider
  4. Verify with a request containing only baseURL to isolate the field mapping

Example fix

// before
{"providerConfig": {"name": "my-openai", "key": "sk-..."}}
// after
{"providerConfig": {"name": "my-openai", "baseURL": "https://api.openai.com", "key": "sk-..."}}
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(provider.BaseURL) == "" {
    return errors.New("provider base URL is required")
}

Type guard

func hasBaseURL(p *conf.Provider) bool { return p != nil && strings.TrimSpace(p.BaseURL) != "" }

Try / catch

provider, err := resolveAIProvider(req)
if err != nil {
    return contractFailure[string](gulu.Ret.NewResultWithMsg(err.Error()))
}

Prevention

When it happens

Trigger: Calling an AI endpoint (e.g. the test-model or list-models contract APIs) with request.ProviderConfig whose baseURL/baseUrl field is empty, whitespace-only, or omitted entirely.

Common situations: User adds a custom AI provider in settings but leaves the API endpoint field blank, an API client builds ProviderConfig without baseURL, or migrating configs where the URL field was renamed and no longer maps.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/5b1d6608569497d4. Report an issue: GitHub.

Appendix: source

Thrown at kernel/api/ai.go:69

	}
	return nil
}

func resolveAIProvider(request apicontract.AIProviderRequest) (*conf.Provider, error) {
	if err := request.ProviderError(); err != nil {
		return nil, err
	}
	if providerConfig := request.ProviderConfig; providerConfig != nil {
		data, err := gulu.JSON.MarshalJSON(providerConfig)
		if err != nil {
			return nil, err
		}
		provider := &conf.Provider{}
		if err = gulu.JSON.UnmarshalJSON(data, provider); err != nil {
			return nil, err
		}
		if strings.TrimSpace(provider.BaseURL) == "" {
			return nil, errors.New("provider base URL is required")
		}
		if err = util.ValidateAIProviderHeaders(provider.Headers); err != nil {
			return nil, err
		}
		ai := &conf.AI{Providers: []*conf.Provider{provider}}
		ai.Normalize()
		if len(ai.Providers) != 1 {
			return nil, errors.New("invalid provider config")
		}
		return ai.Providers[0], nil
	}

	providerID := request.Provider
	for _, provider := range model.Conf.AI.Providers {
		if provider != nil && provider.ID == providerID {
			return provider, nil
		}
	}

View on GitHub (pinned to 9f775e8a12)