{"record":{"id":"108894d9b931c2bd","repo":"AlistGo/alist","slug":"doubao-api-error-code-d-s","errorCode":null,"errorMessage":"[doubao] API error (code: %d): %s","messagePattern":"\\[doubao\\] API error \\(code: (.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao/types.go","lineNumber":401,"sourceCode":"\treturn r.Code == 0\n}\n\n// GetError 获取错误信息\nfunc (r *CommonResp) GetError() error {\n\tif r.IsSuccess() {\n\t\treturn nil\n\t}\n\t// 优先使用message字段\n\terrMsg := r.Message\n\tif errMsg == \"\" {\n\t\terrMsg = r.Msg\n\t}\n\t// 如果error对象存在且有详细消息,则使用error中的信息\n\tif r.Error != nil && r.Error.Message != \"\" {\n\t\terrMsg = r.Error.Message\n\t}\n\n\treturn fmt.Errorf(\"[doubao] API error (code: %d): %s\", r.Code, errMsg)\n}\n\n// UnmarshalData 将data字段解析为指定类型\nfunc (r *CommonResp) UnmarshalData(v interface{}) error {\n\tif !r.IsSuccess() {\n\t\treturn r.GetError()\n\t}\n\n\tif len(r.Data) == 0 {\n\t\treturn nil\n\t}\n\n\treturn json.Unmarshal(r.Data, v)\n}\n","sourceCodeStart":383,"sourceCodeEnd":416,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao/types.go#L383-L416","documentation":"CommonResp.GetError() builds the canonical Doubao API error: the response envelope carried a non-success code. It prefers error.message, falls back to top-level message, then msg, and formats code plus message. Every Doubao request path (d.request and UnmarshalData) routes failures through this, so any Doubao API rejection surfaces as this error.","triggerScenarios":"Doubao/ByteDance backend returns Code != Success in ResponseMetadata — session cookie expired (need re-login), rate limiting, object not found, upload quota exceeded, or invalid parameters on endpoints like /passport/account/info/v2/ or upload config endpoints.","commonSituations":"Long-lived mounts whose cookie/token expired (most common); heavy concurrent uploads hitting rate limits; account region restrictions; API contract changes after Doubao app updates.","solutions":["If the message indicates auth/session expiry, refresh the driver's cookie/credentials in Additional config and re-test","Reduce concurrency/backoff and retry — transient rate-limit codes clear on their own","Search the error message text in Doubao driver issues; cookie-header format changes (missing fields) produce confusing codes","If code is consistently unknown after an app update, the driver may need updating to the new API contract"],"exampleFix":"// before\nreturn fmt.Errorf(\"[doubao] API error (code: %d): %s\", r.Code, errMsg)\n// after — include ResponseMetadata.RequestId so support/issue reports can correlate\nreturn fmt.Errorf(\"[doubao] API error (code: %d): %s (request_id: %s)\", r.Code, errMsg, r.ResponseMetadata.RequestId)","handlingStrategy":"try-catch","validationCode":"if d.Cookie == \"\" { // driver's session credential\n\treturn errors.New(\"doubao session cookie not configured\")\n}","typeGuard":"func isDoubaoAPIError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"[doubao] API error\")","tryCatchPattern":"if isDoubaoAPIError(err) {\n\tif isSessionError(err) { // message mentions login/expired\n\t\treturn reloginAndRetry()\n\t}\n\treturn backoffRetry(3)\n}","preventionTips":["Keep the doubao cookie fresh; schedule re-login before expiry","Back off on rate-limit messages instead of hammering","Include request_id when reporting issues upstream"],"tags":["doubao","api-error","auth","storage-driver"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}