AlistGo/alist · error

[doubao_new] decode response failed (status: %s, content-typ

Error message

[doubao_new] decode response failed (status: %s, content-type: %s, body: %s): %v

What it means

Doubao_new response decoding failure in the generic request helper (util.go:67): the HTTP body could not be unmarshaled into the BaseResp envelope. The message helpfully embeds status, content-type, and the full body, so the cause is usually visible in the error text itself (HTML error page, empty body, truncated JSON).

Source

Thrown at drivers/doubao_new/util.go:67

	}
	if res != nil {
		if v := res.Header().Get("X-Tt-Logid"); v != "" {
			d.TtLogid = v
		} else if v := res.Header().Get("x-tt-logid"); v != "" {
			d.TtLogid = v
		}
	}

	body := res.Body()
	var common BaseResp
	if err = json.Unmarshal(body, &common); err != nil {
		msg := fmt.Sprintf("[doubao_new] decode response failed (status: %s, content-type: %s, body: %s): %v",
			res.Status(),
			res.Header().Get("Content-Type"),
			string(body),
			err,
		)
		return body, fmt.Errorf(msg)
	}
	if common.Code != 0 {
		errMsg := common.Msg
		if errMsg == "" {
			errMsg = common.Message
		}
		return body, fmt.Errorf("[doubao_new] API error (code: %d): %s", common.Code, errMsg)
	}
	if resp != nil {
		if err = json.Unmarshal(body, resp); err != nil {
			return body, err
		}
	}

	return body, nil
}

func getCookieValue(cookie, name string) string {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Read the embedded body snippet in the error message — it identifies the exact page (login redirect, 502, challenge, rate-limit)
  2. If it's an auth/login page: re-authenticate the doubao_new driver (cookies expired)
  3. If it's a proxy error page: fix upstream connectivity or proxy config for the API host
  4. If body is empty with 5xx: retry with backoff, the API node is unhealthy
  5. If a truncated JSON: check proxy response buffering and timeouts on large responses
Defensive patterns

Strategy: type-guard

Validate before calling

// cheap pre-check: sniff content-type before unmarshal
ct := res.Header().Get("Content-Type")
if !strings.Contains(ct, "json") {
    return body, fmt.Errorf("non-JSON response (status %s, ct %s): %s", res.Status(), ct, truncate(body, 512))
}

Type guard

func isJSONBody(res *resty.Response) bool {
    ct := res.Header().Get("Content-Type")
    return strings.Contains(ct, "json") || bytes.HasPrefix(bytes.TrimSpace(res.Body()), []byte("{"))
}

Try / catch

if err := json.Unmarshal(body, &common); err != nil {
    if !isJSONBody(res) {
        // auth challenge / proxy page: refresh session, not a decode bug
        return body, fmt.Errorf("non-JSON response (%s): re-auth likely required", res.Status())
    }
    return body, err
}

Prevention

When it happens

Trigger: Any API call whose response is not JSON: gateway returning an HTML 4xx/5xx page, WAF challenge/redirect page, empty body from a 502, gzipped body not decoded, or a JSON body truncated by a proxy timeout.

Common situations: Cloudflare/edge protection injecting challenge pages when the session cookie expires, reverse proxy buffering limits truncating large listings, rate-limit pages, or API host changes returning HTML redirects to a login page.

Related errors


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