{"record":{"id":"4ba469d57bc2080f","repo":"AlistGo/alist","slug":"ocr-error-jsoniter-get-vres-body-msg-tos","errorCode":null,"errorMessage":"ocr error:\" + jsoniter.Get(vRes.Body(), \"msg\").ToString()","messagePattern":"ocr error:\" \\+ jsoniter\\.Get\\(vRes\\.Body\\(\\), \"msg\"\\)\\.ToString\\(\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/cloudreve/util.go","lineNumber":138,"sourceCode":"\tif needCaptcha {\n\t\tvar captcha string\n\t\terr = d.request(http.MethodGet, \"/site/captcha\", nil, &captcha)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(captcha) == 0 {\n\t\t\treturn errors.New(\"can not get captcha\")\n\t\t}\n\t\ti := strings.Index(captcha, \",\")\n\t\tdec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(captcha[i+1:]))\n\t\tvRes, err := base.RestyClient.R().SetMultipartField(\n\t\t\t\"image\", \"validateCode.png\", \"image/png\", dec).\n\t\t\tPost(setting.GetStr(conf.OcrApi))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif jsoniter.Get(vRes.Body(), \"status\").ToInt() != 200 {\n\t\t\treturn errors.New(\"ocr error:\" + jsoniter.Get(vRes.Body(), \"msg\").ToString())\n\t\t}\n\t\tcaptchaCode = jsoniter.Get(vRes.Body(), \"result\").ToString()\n\t}\n\tvar resp Resp\n\terr = d.request(http.MethodPost, loginPath, func(req *resty.Request) {\n\t\treq.SetBody(base.Json{\n\t\t\t\"username\":    d.Addition.Username,\n\t\t\t\"Password\":    d.Addition.Password,\n\t\t\t\"captchaCode\": captchaCode,\n\t\t})\n\t}, &resp)\n\treturn err\n}\n\nfunc convertSrc(obj model.Obj) map[string]interface{} {\n\tm := make(map[string]interface{})\n\tvar dirs []string\n\tvar items []string","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/cloudreve/util.go#L120-L156","documentation":"Raised after the captcha image was forwarded to the configured OCR HTTP service (setting conf.OcrApi, posted as multipart field 'image') and that service answered with a JSON body whose status is not 200. The OCR service's own msg field is appended, e.g. 'ocr error:model not loaded'.","triggerScenarios":"doLogin with captcha enabled: image POSTed to setting.GetStr(conf.OcrApi); response body parsed with jsoniter and status != 200. Happens when the OCR endpoint is misconfigured, down, returns HTML (proxy error page), or the ddddocr-style service fails to recognize/load.","commonSituations":"conf.OcrApi left pointing at default/placeholder URL; OCR container not running or crashing on the PNG; reverse proxy in front of the OCR service returning 502 HTML so status parses to 0; OCR service version that expects a different field name than 'image'.","solutions":["Set the OcrApi setting to a working OCR service (e.g. a deployed ddddocr API: https://github.com/sml2h3/ddddocr) and test it with a manual multipart POST of a PNG.","Check the OCR service logs — its msg field names the exact failure (model missing, decode error).","Disable login captcha on the Cloudrebve side so no OCR is needed.","Ensure the URL in OcrApi is the full endpoint (scheme+host+path) and reachable from the alist/OpenList host."],"exampleFix":"# before: placeholder OCR api\nPUT /api/setting/ocr_api  -> \"\"\n# after: working ddddocr service\nPUT /api/setting/ocr_api  -> \"http://127.0.0.1:9898\"","handlingStrategy":"validation","validationCode":"// health-check the OCR service before relying on it during login\nif setting.GetStr(conf.OcrApi) == \"\" {\n    return errors.New(\"OcrApi not configured; cannot solve login captcha\")\n}\nif resp, err := http.Get(setting.GetStr(conf.OcrApi) + \"/ping\"); err != nil || resp.StatusCode != 200 {\n    return errors.New(\"OCR service unreachable\")\n}","typeGuard":"func isOcrError(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"ocr error:\")\n}","tryCatchPattern":"if err != nil {\n    if strings.HasPrefix(err.Error(), \"ocr error:\") {\n        // captcha/OCR path failed: fix OcrApi or disable captcha rather than retrying blindly\n        log.Printf(\"ocr login failed: %s; check conf.OcrApi service\", err)\n    }\n    return err\n}","preventionTips":["Deploy and health-check a ddddocr-style OCR service before enabling captcha logins","Set conf.OcrApi to a tested full URL","Disable captcha on the Cloudrebve side when headless mounting"],"tags":["cloudreve","ocr","captcha","configuration","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}