{"record":{"id":"044c7c9fe91b5a08","repo":"AlistGo/alist","slug":"upload-tk-is-empty","errorCode":null,"errorMessage":"upload tk is empty","messagePattern":"upload tk is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/yunpan360/upload.go","lineNumber":462,"sourceCode":"\n\turl := buildJSQueryURL(d.uploadBaseURL(addrResp), \"Upload.commit4Web\", d.uploadDataParams(auth, plan))\n\turl = appendHostQuery(url, addrResp.Data.HTTP)\n\n\tvar resp openUploadFinalizeResp\n\terr = d.uploadRequest(ctx, http.MethodPost, url, auth.AccessToken, contentType, body, &resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &resp, nil\n}\n\nfunc (d *Yunpan360) openFinalizeUpload(ctx context.Context, auth *OpenAuthInfo, resp *openUploadFinalizeResp) error {\n\tif resp == nil || resp.autoCommit() {\n\t\treturn nil\n\t}\n\ttk := strings.TrimSpace(resp.stringValue(\"tk\"))\n\tif tk == \"\" {\n\t\treturn errors.New(\"upload tk is empty\")\n\t}\n\n\tsignParams := map[string]string{\n\t\t\"tk\": tk,\n\t}\n\tbody, contentType, err := createMultipartForm(\"\", map[string]string{\n\t\t\"qid\":  auth.Qid,\n\t\t\"tk\":   tk,\n\t\t\"sign\": openSign(auth.AccessToken, auth.Qid, \"Sync.addFileToApi\", signParams),\n\t}, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn d.uploadRequest(ctx, http.MethodPost, buildJSQueryURL(openAPIURL(d.EcsEnv), \"Sync.addFileToApi\", nil), auth.AccessToken, contentType, body, nil)\n}\n\nfunc (d *Yunpan360) findUploadedObject(ctx context.Context, targetPath string) (model.Obj, error) {","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/yunpan360/upload.go#L444-L480","documentation":"Thrown by openFinalizeUpload during an api_key-mode Yunpan360 upload when the server's upload response does not auto-commit and contains no \"tk\" token. After uploading file bytes, some flows require a second Sync.addFileToApi call signed with tk to register the file; a missing tk (trimmed empty) means the finalize step cannot be signed or sent, so the upload would strand as orphaned data.","triggerScenarios":"The upload endpoint returns a JSON envelope where autoCommit is false and the tk field is absent or empty — typically because the session/upload handshake is out of sync (stale auth token, mismatched qid) or the server changed the finalize protocol.","commonSituations":"Long-running uploads whose open auth token expired mid-flight; multi-step uploads interrupted and retried at the wrong phase; API-side changes to the finalize handshake; large-file paths that behave differently from simple ones.","solutions":["Retry the whole upload from the start so a fresh auth token and upload session are used","Confirm the open auth credentials (api_key, qid) are current by re-saving the storage config","Update the yunpan360 driver if the finalize protocol changed server-side"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"upload tk is empty\") {\n    // finalize handshake desynced: restart upload with fresh auth\n    return d.Put(ctx, dstDir, file, up)\n}","preventionTips":["Restart the entire upload (not just finalize) on tk errors — auth/session must stay in one flow","Keep open-API credentials current; re-save storage config periodically","Update the driver when the finalize protocol changes"],"tags":["yunpan360","upload","finalize","open-api","server-side"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}