{"record":{"id":"bb8d54160f2dadba","repo":"chenhg5/cc-connect","slug":"yuanbao-sign-token-api-returned-d-s","errorCode":null,"errorMessage":"yuanbao: sign token API returned %d: %s","messagePattern":"yuanbao: sign token API returned (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/yuanbao/sign.go","lineNumber":160,"sourceCode":"\t\t\tcontinue\n\t\t}\n\t\treq.Header.Set(\"Content-Type\", \"application/json\")\n\t\treq.Header.Set(\"X-AppVersion\", \"cc-connect-yuanbao/1.0.0\")\n\t\treq.Header.Set(\"X-Instance-Id\", fmt.Sprintf(\"%d\", instanceID))\n\t\treq.Header.Set(\"X-Bot-Version\", \"cc-connect-yuanbao/1.0.0\")\n\t\tif routeEnv != \"\" {\n\t\t\treq.Header.Set(\"X-Route-Env\", routeEnv)\n\t\t}\n\n\t\tresp, err := client.Do(req)\n\t\tif err != nil {\n\t\t\tlastErr = fmt.Errorf(\"yuanbao: request failed: %w\", err)\n\t\t\tcontinue\n\t\t}\n\t\trespBody, _ := io.ReadAll(resp.Body)\n\t\t_ = resp.Body.Close()\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tlastErr = fmt.Errorf(\"yuanbao: sign token API returned %d: %s\", resp.StatusCode, string(respBody))\n\t\t\tcontinue\n\t\t}\n\n\t\tvar result struct {\n\t\t\tCode int `json:\"code\"`\n\t\t\tData *struct {\n\t\t\t\tToken    string `json:\"token\"`\n\t\t\t\tBotID    string `json:\"bot_id\"`\n\t\t\t\tDuration int    `json:\"duration\"`\n\t\t\t\tProduct  string `json:\"product\"`\n\t\t\t\tSource   string `json:\"source\"`\n\t\t\t} `json:\"data\"`\n\t\t}\n\t\tif err := json.Unmarshal(respBody, &result); err != nil {\n\t\t\tlastErr = fmt.Errorf(\"yuanbao: parse response: %w\", err)\n\t\t\tcontinue\n\t\t}\n\t\tif result.Code == 10099 && attempt < maxRetries {","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/yuanbao/sign.go#L142-L178","documentation":"The yuanbao sign-token API responded with an HTTP status other than 200. fetchToken records the status code plus the raw response body in the error and retries; after the retry budget is exhausted the last error is returned to the caller. The embedded body snippet is the server's own explanation.","triggerScenarios":"Any fetchToken attempt (via getToken or VerifyCredentials) where resp.StatusCode != http.StatusOK — e.g. 401 from bad app_key/app_secret, 403 from IP allowlist, 429 rate limit, 5xx server outage.","commonSituations":"Wrong or revoked app_secret in bot_token, calling an incorrect api_domain that answers 404, the sign service rate-limiting retries, server-side incident returning 500/502.","solutions":["Read the body snippet in the error message — it contains the server's status-specific reason.","If 401/403: re-check bot_token (app_key:app_secret) in config.toml and regenerate credentials if revoked.","If 429: back off and retry later; reduce how often tokens are refreshed.","If 5xx: verify the yuanbao service status; the internal retry loop may already absorb transient failures."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"data, err := VerifyCredentials(key, secret, domain, route)\nif err != nil {\n    var httpErr *HTTPStatusError\n    if errors.As(err, &httpErr) && httpErr.Code == 429 {\n        time.Sleep(backoff); retry()\n    }\n}","preventionTips":["Keep bot_token credentials current; rotate before expiry","Respect 429 responses with exponential backoff","Watch upstream status pages for 5xx incidents"],"tags":["http","api","authentication","upstream"],"backgroundTag":"http-error-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}