{"record":{"id":"a4d2b0f9e98bf35d","repo":"AlistGo/alist","slug":"create-oss-client-failed-w","errorCode":null,"errorMessage":"create oss client failed: %w","messagePattern":"create oss client failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/guangyapan/driver.go","lineNumber":413,"sourceCode":"\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 {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif taskID == \"\" {\n\t\treturn nil","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/guangyapan/driver.go#L395-L431","documentation":"Thrown when aliyun-oss-go-sdk's oss.New() rejects the parameters used to build an OSS client for a GuangYaPan upload: the endpoint URL, AccessKeyID, SecretAccessKey, or STS SecurityToken derived from the upload token. oss.New only parses and validates the endpoint/credential strings locally, so a failure here means malformed data, not a network problem. The %w chain preserves the SDK's underlying reason (most often a malformed endpoint URL after normalizeOSSEndpoint).","triggerScenarios":"Put() reaches the direct-OSS branch after the upload token passes the completeness check (token.EndPoint/BucketName/AccessKeyID/SecretAccessKey all non-empty), and oss.New(normalizeOSSEndpoint(token.EndPoint, token.BucketName), ...) fails to parse the constructed endpoint (bad scheme, unparseable host) or the credential strings.","commonSituations":"GuangYaPan's get_res_center_token API changed its endpoint format (adds scheme or path unexpectedly); a proxy or region rewrite mangles the endpoint; the STS credentials field layout changed so creds fall back to empty/odd values.","solutions":["Log the exact wrapped SDK error and the normalized endpoint string to see which parameter oss.New rejected.","Inspect normalizeOSSEndpoint's output for the failing token.EndPoint value and confirm it is a valid host (optionally with https:// scheme).","Check whether the upload token's AccessKeyID/SecretAccessKey/SessionToken were populated from out.Data.Creds after the top-level fields came back empty.","If the provider changed the token payload shape, update uploadTokenData/getUploadToken parsing to match the current API response."],"exampleFix":"// before\nossEndpoint := normalizeOSSEndpoint(token.EndPoint, token.BucketName)\nclient, err := oss.New(ossEndpoint, token.AccessKeyID, token.SecretAccessKey, oss.SecurityToken(token.SessionToken))\nif err != nil {\n    return fmt.Errorf(\"create oss client failed: %w\", err)\n}\n\n// after - include endpoint in the error for diagnosis\nossEndpoint := normalizeOSSEndpoint(token.EndPoint, token.BucketName)\nclient, err := oss.New(ossEndpoint, token.AccessKeyID, token.SecretAccessKey, oss.SecurityToken(token.SessionToken))\nif err != nil {\n    return fmt.Errorf(\"create oss client failed (endpoint=%s): %w\", ossEndpoint, err)\n}","handlingStrategy":"validation","validationCode":"// before building the OSS client, sanity-check the token fields\nif u, err := url.Parse(token.EndPoint); err != nil || u.Host == \"\" {\n    return fmt.Errorf(\"upload token endpoint invalid: %q\", token.EndPoint)\n}\nif token.AccessKeyID == \"\" || token.SecretAccessKey == \"\" {\n    return errors.New(\"upload token credentials missing\")\n}","typeGuard":null,"tryCatchPattern":"if err := d.Put(ctx, dstDir, file, overwrite); err != nil {\n    if strings.Contains(err.Error(), \"create oss client failed\") {\n        // token/endpoint problem: drop cached upload token and let the next attempt fetch a fresh one\n        log.Warnf(\"oss client creation failed, will re-request upload token: %v\", err)\n    }\n    return err\n}","preventionTips":["Validate endpoint and credential fields before calling oss.New so failures surface with clearer context.","Treat upload tokens as short-lived: never cache them across long periods.","Log the normalized endpoint on failure to distinguish provider changes from local config issues."],"tags":["oss","upload","endpoint","credentials","guangyapan"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}