Tencent/WeKnora · error

create verification request failed: %w

Error message

create verification request failed: %w

What it means

verifyCredentials builds a GET request to the WeKnora Cloud /api/v1/health endpoint with http.NewRequestWithContext. If request construction fails (almost always a malformed URL, e.g. an empty or invalid WeKnoraCloudBaseURL), the error is wrapped as 'create verification request failed: %w'.

Source

Thrown at internal/application/service/weknoracloud.go:63

	if err := s.verifyCredentials(ctx, appID, appSecret); err != nil {
		return fmt.Errorf("credential verification failed: %w", err)
	}

	tenantID := types.MustTenantIDFromContext(ctx)
	return s.updateTenantCredentials(ctx, tenantID, appID, appSecret)
}

// verifyCredentials 向 WeKnoraCloud /api/v1/health 发送带签名头的 GET。
//
// 注意:health 一般为探活接口,远端常不校验 APPID/SECRET 或签名;HTTP 200 通常只表示
// 「网关/服务可达」,不能严格证明凭证有效。若需强校验,应改为调用必须鉴权的业务接口。
func (s *weKnoraCloudService) verifyCredentials(ctx context.Context, appID, appSecret string) error {
	baseURL := strings.TrimRight(provider.WeKnoraCloudBaseURL, "/")
	healthURL := baseURL + "/api/v1/health"

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, healthURL, nil)
	if err != nil {
		return fmt.Errorf("create verification request failed: %w", err)
	}

	requestID := fmt.Sprintf("verify-%d", time.Now().UnixNano())
	signHeaders := modelsutils.Sign(appID, appSecret, requestID, "{}")
	for k, v := range signHeaders {
		req.Header.Set(k, v)
	}

	logger.Infof(ctx, "credential verification request: method=GET url=%s app_id=%s request_id=%s ",
		healthURL, appID, requestID)

	clientCfg := utils.DefaultSSRFSafeHTTPClientConfig()
	clientCfg.Timeout = 10 * time.Second
	client := utils.NewSSRFSafeHTTPClient(clientCfg)
	resp, err := client.Do(req)
	if err != nil {
		logger.Warnf(ctx, "credential verification HTTP failed: url=%s err=%v", healthURL, err)
		return fmt.Errorf("service unreachable: %w", err)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set provider.WeKnoraCloudBaseURL to a valid absolute https:// URL before saving credentials.
  2. Check the config/env source for unresolved placeholders or stray whitespace and trim/expand them.
  3. Validate the base URL at startup (url.Parse) so misconfiguration is caught early, not at credential save time.
  4. Print the composed healthURL (without secrets) in debug logs to spot malformed composition.

Example fix

// before
baseURL := cfg.WeKnoraCloudBaseURL // "" -> parse error
// after
if u, err := url.Parse(cfg.WeKnoraCloudBaseURL); err != nil || u.Scheme == "" || u.Host == "" {
	return errors.New("WeKnoraCloudBaseURL must be an absolute http(s) URL")
}
baseURL := strings.TrimRight(cfg.WeKnoraCloudBaseURL, "/")
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(baseURL))
if err != nil || u.Scheme == "" || u.Host == "" {
	return fmt.Errorf("invalid WeKnoraCloudBaseURL %q: %w", baseURL, err)
}

Try / catch

if err := svc.SaveCredentials(ctx, appID, appSecret); err != nil {
	if strings.Contains(err.Error(), "create verification request failed") {
		// baseURL is malformed; block save and ask for a valid https URL
		return configError("WeKnoraCloudBaseURL", err)
	}
	return err
}

Prevention

When it happens

Trigger: SaveCredentials -> verifyCredentials where baseURL is empty, contains control characters, or is otherwise not a parseable URL, making http.NewRequestWithContext return an error.

Common situations: WeKnoraCloudBaseURL not configured (empty string yields URL "/api/v1/health" which fails to parse); config value contains spaces/newlines; mis-templated env var (literal "${...}" left unresolved).

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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