{"record":{"id":"1bef4cf66e16709a","repo":"Tencent/WeKnora","slug":"create-request-w-1bef4c","errorCode":null,"errorMessage":"create request: %w","messagePattern":"create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/datasource/connector/yuque/client.go","lineNumber":64,"sourceCode":"// client lifetime (not per request) to keep sync logs readable at thousand-doc scale.\nfunc (c *client) doRequest(ctx context.Context, method, path string, result interface{}) error {\n\tconst (\n\t\tmaxRetries    = 3\n\t\tmax5xxRetries = 1\n\t\tretry5xxDelay = 2 * time.Second\n\t)\n\tvar lastErr error\n\tbackoff := []time.Duration{2 * time.Second, 4 * time.Second, 8 * time.Second}\n\n\tc.logTokenOnce.Do(func() {\n\t\tlogger.Infof(ctx, \"[Yuque] client configured token=%s base=%s\", redactToken(c.token), c.baseURL)\n\t})\n\n\tfor attempt := 0; attempt <= maxRetries; attempt++ {\n\t\treqURL := c.baseURL + path\n\t\treq, err := http.NewRequestWithContext(ctx, method, reqURL, nil)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"create request: %w\", err)\n\t\t}\n\t\treq.Header.Set(\"X-Auth-Token\", c.token)\n\t\treq.Header.Set(\"User-Agent\", userAgent)\n\t\treq.Header.Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\n\t\tif attempt == 0 {\n\t\t\tlogger.Infof(ctx, \"[Yuque] %s %s\", method, path)\n\t\t} else {\n\t\t\tlogger.Infof(ctx, \"[Yuque] %s %s (retry %d/%d)\", method, path, attempt, maxRetries)\n\t\t}\n\n\t\tresp, err := c.httpClient.Do(req)\n\t\tif err != nil {\n\t\t\tlastErr = fmt.Errorf(\"execute request: %w\", err)\n\t\t\tif attempt < maxRetries {\n\t\t\t\tif sErr := sleepCtx(ctx, backoff[attempt]); sErr != nil {\n\t\t\t\t\treturn sErr\n\t\t\t\t}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/datasource/connector/yuque/client.go#L46-L82","documentation":"The Yuque client's doRequest builds each HTTP call with http.NewRequestWithContext. If request construction fails (invalid method string, unparsable URL from baseURL+path, or a bad/nil context body), it returns \"create request: %w\". This happens before any network I/O, so it indicates a programming or configuration error rather than a server problem.","triggerScenarios":"Any of Ping, GetCurrentUser, ListUserGroups, listReposPaginated, ListBookDocs, GetDocDocDetail via doRequest when the method verb is invalid, the baseURL is malformed (bad scheme, spaces, control chars), or path produces an unparseable URL.","commonSituations":"baseURL configured with a typo like \"yuque.com\" (no scheme) or a trailing space from an env var; an empty baseURL making the URL unparseable; a custom caller passing a non-standard HTTP method.","solutions":["Check the YUQUE base URL configuration: it must be an absolute URL with scheme, e.g. https://www.yuque.com/api/v2, with no whitespace.","Trim whitespace and validate the URL with url.Parse before constructing the client.","Verify the method argument is a valid HTTP verb (GET/POST/...).","Ensure the context passed in is a real, non-nil context."],"exampleFix":"// before\nbaseURL := os.Getenv(\"YUQUE_BASE_URL\") // \"yuque.com/api/v2\"\n// after\nu, err := url.Parse(strings.TrimSpace(os.Getenv(\"YUQUE_BASE_URL\")))\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid YUQUE_BASE_URL: %q\", os.Getenv(\"YUQUE_BASE_URL\"))\n}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(strings.TrimSpace(baseURL + path))\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid Yuque URL %q: %v\", baseURL+path, err)\n}","typeGuard":"func validURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"err := client.Ping(ctx)\nif err != nil && strings.HasPrefix(err.Error(), \"create request:\") {\n    // configuration bug: fix baseURL/method, do not retry\n    return err\n}","preventionTips":["Trim and validate the base URL at client construction time.","Use constants for HTTP methods instead of free strings.","Add a constructor-time Ping to fail fast on bad configuration."],"tags":["go","http","url","yuque"],"backgroundTag":"invalid-url","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}