{"record":{"id":"1dc0e861e38bdc14","repo":"AlistGo/alist","slug":"upload-token-is-incomplete","errorCode":null,"errorMessage":"upload token is incomplete","messagePattern":"upload token is incomplete","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/guangyapan/driver.go","lineNumber":407,"sourceCode":"\t\treturn errors.New(\"file name is empty\")\n\t}\n\n\tparentID := dstDir.GetID()\n\n\ttoken, code, err := d.getUploadToken(ctx, parentID, name, file.GetSize())\n\tif err != nil {\n\t\treturn err\n\t}\n\ttaskID := strings.TrimSpace(token.TaskID)\n\tif code == 156 {\n\t\tif taskID == \"\" {\n\t\t\treturn errors.New(\"instant upload returns empty task id\")\n\t\t}\n\t\treturn d.waitUploadTaskInfo(ctx, taskID)\n\t}\n\n\tif token.ObjectPath == \"\" || token.BucketName == \"\" || token.EndPoint == \"\" || token.AccessKeyID == \"\" || token.SecretAccessKey == \"\" {\n\t\treturn errors.New(\"upload token is incomplete\")\n\t}\n\n\tossEndpoint := normalizeOSSEndpoint(token.EndPoint, token.BucketName)\n\tclient, err := oss.New(ossEndpoint, token.AccessKeyID, token.SecretAccessKey, oss.SecurityToken(token.SessionToken))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create oss client failed: %w\", err)\n\t}\n\tbucket, err := client.Bucket(token.BucketName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create oss bucket failed: %w\", err)\n\t}\n\n\tif file.GetSize() == 0 {\n\t\tif err := bucket.PutObject(token.ObjectPath, strings.NewReader(\"\")); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif err := d.multipartUploadToOSS(ctx, bucket, token.ObjectPath, file, up); err != nil {","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/guangyapan/driver.go#L389-L425","documentation":"For a normal (non-instant) upload, GuangYaPan exchanges an upload token that must contain OSS credentials: ObjectPath, BucketName, EndPoint, AccessKeyID, SecretAccessKey (SessionToken is optional). If any mandatory field is empty the driver cannot construct the aliyun-OSS client and refuses with this aggregate error.","triggerScenarios":"getUploadToken succeeds but returns a partially populated struct — provider changed field names/casing, returned a different response envelope, or the account lacks OSS upload authorization so the credentials block is omitted.","commonSituations":"Provider API drift after an update; new/unverified accounts without storage quota; token requested for a path the account cannot write to.","solutions":["Verify the account can upload via the provider's official app","Update the OpenList/Alist driver to the latest version (field-mapping fixes land there)","Retry after re-login (refresh tokens) in case the grant was partial","If it persists, capture the token response (debug logs) and report the changed schema"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"missing := []string{}\nif token.ObjectPath == \"\" { missing = append(missing, \"object_path\") }\nif token.BucketName == \"\" { missing = append(missing, \"bucket_name\") }\nif token.EndPoint == \"\" { missing = append(missing, \"endpoint\") }\nif token.AccessKeyID == \"\" { missing = append(missing, \"access_key_id\") }\nif token.SecretAccessKey == \"\" { missing = append(missing, \"secret_access_key\") }\nif len(missing) > 0 {\n\treturn fmt.Errorf(\"upload token missing fields: %s\", strings.Join(missing, \", \"))\n}","typeGuard":"func uploadTokenComplete(t UploadToken) bool {\n\treturn t.ObjectPath != \"\" && t.BucketName != \"\" && t.EndPoint != \"\" && t.AccessKeyID != \"\" && t.SecretAccessKey != \"\"\n}","tryCatchPattern":"if err := d.Put(ctx, dir, file, up); err != nil {\n\tif strings.Contains(err.Error(), \"upload token is incomplete\") {\n\t\t// re-auth then retry once; stale/partial grants sometimes resolve\n\t\tif rerr := d.refreshToken(ctx); rerr == nil {\n\t\t\treturn d.Put(ctx, dir, file, up)\n\t\t}\n\t\treturn errors.New(\"provider did not issue full OSS credentials; verify account upload rights and update the driver\")\n\t}\n\treturn err\n}","preventionTips":["Confirm the account can upload through the provider's official client before debugging OpenList","Update OpenList/Alist regularly so token-response field mappings track provider API changes","Re-login (fresh tokens) when uploads suddenly start failing after working","Log (at debug level) the token response keys when this fires to spot renamed fields"],"tags":["guangyapan","upload","oss","api","configuration"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}