Tencent/WeKnora · error

create request: %w

Error message

create request: %w

What it means

applyUploadURLs builds the POST to baseURL/file-urls/batch with http.NewRequestWithContext; if request construction fails (invalid method/URL), it returns "create request: %w". Since the method is a constant POST, this almost always means the configured baseURL is not a valid URL.

Source

Thrown at internal/infrastructure/docparser/mineru_cloud_converter.go:134

	}

	payload := map[string]interface{}{
		"files":          []map[string]string{{"name": fileName, "data_id": uuid.New().String()}},
		"model_version":  modelVersion,
		"is_ocr":         c.ocrEnable,
		"enable_formula": c.formulaEnable,
		"enable_table":   c.tableEnable,
		"language":       c.language,
	}

	body, err := json.Marshal(payload)
	if err != nil {
		return "", "", fmt.Errorf("marshal payload: %w", err)
	}

	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+"/file-urls/batch", bytes.NewReader(body))
	if err != nil {
		return "", "", fmt.Errorf("create request: %w", err)
	}
	httpReq.Header.Set("Authorization", "Bearer "+c.apiKey)
	httpReq.Header.Set("Content-Type", "application/json")

	client := utils.NewSSRFSafeHTTPClient(utils.SSRFSafeHTTPClientConfig{Timeout: 30 * time.Second, MaxRedirects: 5})
	resp, err := client.Do(httpReq)
	if err != nil {
		return "", "", fmt.Errorf("HTTP request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		respBody, _ := io.ReadAll(resp.Body)
		return "", "", fmt.Errorf("API status %d: %s", resp.StatusCode, string(respBody))
	}

	var result batchApplyResponse
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check the wrapped cause and print/inspect the configured baseURL — it must be a full absolute URL including scheme.
  2. Fix the env var/config to e.g. https://mineru.net/api/v4 (no spaces, no quotes, correct scheme).
  3. Trim whitespace with strings.TrimSpace when loading the baseURL from environment/config.
  4. Validate the URL with url.Parse at startup and fail fast if invalid.

Example fix

// before
baseURL := os.Getenv("MINERU_BASE_URL") // "mineru.net/api/v4" — no scheme
// after
baseURL := strings.TrimSpace(os.Getenv("MINERU_BASE_URL"))
if u, err := url.Parse(baseURL); err != nil || u.Scheme == "" {
    return nil, nil, fmt.Errorf("invalid mineru base url %q", baseURL)
}
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(baseURL))
if err != nil || u.Scheme != "https" || u.Host == "" {
    return fmt.Errorf("mineru baseURL must be an absolute https URL, got %q", baseURL)
}

Type guard

func isValidBaseURL(raw string) bool {
    u, err := url.Parse(strings.TrimSpace(raw))
    return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}

Try / catch

res, err := converter.Read(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "create request") {
        return fmt.Errorf("mineru baseURL %q is not a valid URL; fix the endpoint config (include https://)", baseURL)
    }
    return err
}

Prevention

When it happens

Trigger: Read -> applyUploadURLs where http.NewRequestWithContext fails because c.baseURL + "/file-urls/batch" does not parse as a valid URL (e.g. missing scheme, control characters, spaces).

Common situations: baseURL env var set without scheme ("mineru.net" instead of "https://mineru.net"); trailing spaces/newline in config; misparsed YAML/env config injecting quotes or whitespace into the URL.

Related errors


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