{"record":{"id":"d8d348dff01737cb","repo":"AlistGo/alist","slug":"string-res","errorCode":null,"errorMessage":"{string(res)}","messagePattern":"\\{string\\(res\\)\\}","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/aliyundrive/util.go","lineNumber":203,"sourceCode":"\t\t\t\t\t\t\"drive_id\":          d.DriveId,\n\t\t\t\t\t\t\"file_id\":           srcId,\n\t\t\t\t\t\t\"to_drive_id\":       d.DriveId,\n\t\t\t\t\t\t\"to_parent_file_id\": dstId,\n\t\t\t\t\t},\n\t\t\t\t\t\"url\": url,\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"resource\": \"file\",\n\t\t})\n\t}, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tstatus := utils.Json.Get(res, \"responses\", 0, \"status\").ToInt()\n\tif status < 400 && status >= 100 {\n\t\treturn nil\n\t}\n\treturn errors.New(string(res))\n}\n","sourceCodeStart":185,"sourceCodeEnd":205,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/aliyundrive/util.go#L185-L205","documentation":"Returned after a batch operation (the get download URLs / batch task call in aliyundrive/util.go) where the per-item result inside responses[0].status is an HTTP error code (>=400 or <100). The raw response body is returned verbatim as the error, so the message is whatever JSON the server embedded for the failed batch item.","triggerScenarios":"The batch API call itself returned 2xx, but the first item's status field (e.g. 404, 429, 403) indicates that item failed — common for expired download URLs on deleted files, rate-limited items, or permission-revoked shares inside an otherwise successful batch response.","commonSituations":"Listing then immediately linking files that were deleted or moved server-side between calls; batch-linking many files quickly and hitting per-item throttling; tokens lacking scope for specific files. Because the whole body is dumped, the error string is a large JSON blob in logs.","solutions":["Parse the nested responses[0] object (code/content) to get the real per-item error instead of relying on the raw dump","Refresh the file list (the target file may be gone) and retry the single item","Add per-item backoff when many links are requested in one batch to avoid 429 item statuses","If a livp/photo edge case, ensure the request targets the correct domain endpoint for that file type"],"exampleFix":"// before\nreturn errors.New(string(res))\n\n// after — extract the per-item message\nmsg := utils.Json.Get(res, \"responses\", 0, \"content\", \"message\").ToString()\nif msg == \"\" {\n    msg = string(res)\n}\nreturn errors.New(msg)","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"// Go\nfunc isBatchItemFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"\\\"responses\\\"\")\n}","tryCatchPattern":"_, err := d.request(...)\nif isBatchItemFailure(err) {\n    // re-fetch listing; per-item 404 usually means the file vanished\n    // fall back to a single-item, non-batch request for the survivors\n}","preventionTips":["Inspect responses[i].status per item instead of trusting the batch HTTP status","Refresh listings before batch-linking stale IDs","Extract the nested message field rather than dumping the whole body into logs"],"tags":["aliyundrive","batch-api","partial-failure","raw-body"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}