AlistGo/alist · error

ocr error: empty result

Error message

ocr error: empty result

What it means

CloudreveV4 login: the OCR service answered status 200 but its result field was an empty string, so there is no captcha code to submit. This isolates the failure to the OCR stage (recognition produced nothing) rather than transport or service errors.

Source

Thrown at drivers/cloudreve_v4/util.go:161

		}
		if !strings.HasPrefix(captcha.Image, "data:image/png;base64,") {
			return errors.New("can not get captcha")
		}
		loginBody["ticket"] = captcha.Ticket
		i := strings.Index(captcha.Image, ",")
		dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(captcha.Image[i+1:]))
		vRes, err := base.RestyClient.R().SetMultipartField(
			"image", "validateCode.png", "image/png", dec).
			Post(setting.GetStr(conf.OcrApi))
		if err != nil {
			return err
		}
		if jsoniter.Get(vRes.Body(), "status").ToInt() != 200 {
			return errors.New("ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString())
		}
		captchaCode := jsoniter.Get(vRes.Body(), "result").ToString()
		if captchaCode == "" {
			return errors.New("ocr error: empty result")
		}
		loginBody["captcha"] = captchaCode
	}
	var token TokenResponse
	err = d.request(http.MethodPost, "/session/token", func(req *resty.Request) {
		req.SetBody(loginBody)
	}, &token)
	if err != nil {
		return err
	}
	d.AccessToken, d.RefreshToken = token.Token.AccessToken, token.Token.RefreshToken
	op.MustSaveDriverStorage(d)
	return nil
}

func (d *CloudreveV4) refreshToken() error {
	var token Token
	if token.RefreshToken == "" {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Manually POST the exact captcha PNG to the OCR service and inspect the full JSON — confirm the result key and value.
  2. Retry login (the driver already retries up to 5 times on 'CAPTCHA not match', but empty OCR aborts; a retry may get a fresh, more readable captcha).
  3. Switch to a better OCR service/model for this captcha style.
  4. Disable captcha on the Cloudrebve V4 site to avoid the OCR path.
Defensive patterns

Strategy: retry

Validate before calling

captchaCode := jsoniter.Get(vRes.Body(), "result").ToString()
if captchaCode == "" { return errors.New("ocr error: empty result") }

Try / catch

if err := d.doLogin(true); err != nil {
    if err.Error() == "ocr error: empty result" {
        time.Sleep(time.Second)
        return d.doLogin(true) // fresh captcha image may OCR cleanly
    }
    return err
}

Prevention

When it happens

Trigger: jsoniter.Get(vRes.Body(), "result").ToString() == "" after a 200 OCR response. Happens when the OCR model returns an empty prediction for the image, the response shape differs (result nested elsewhere), or the image bytes sent were corrupt.

Common situations: ddddocr returning empty for hard captcha images; service returning {"status":200} with data under a different key; truncated base64 decode of the captcha image; wrong captcha type yielding an image OCR cannot read.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/561ef6f00768ac92. Report an issue: GitHub.