{"record":{"id":"63e40aa11e86b03f","repo":"Tencent/WeKnora","slug":"failed-to-upload-file-to-oss-w","errorCode":null,"errorMessage":"failed to upload file to OSS: %w","messagePattern":"failed to upload file to OSS: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/file/oss.go","lineNumber":210,"sourceCode":"\t\t\t&oss.PutObjectRequest{\n\t\t\t\tBucket:      oss.Ptr(s.bucketName),\n\t\t\t\tKey:         oss.Ptr(objectName),\n\t\t\t\tContentType: oss.Ptr(contentType),\n\t\t\t},\n\t\t\tsrc,\n\t\t)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to upload file to OSS (multipart): %w\", err)\n\t\t}\n\t} else {\n\t\t_, err = s.client.PutObject(ctx, &oss.PutObjectRequest{\n\t\t\tBucket:      oss.Ptr(s.bucketName),\n\t\t\tKey:         oss.Ptr(objectName),\n\t\t\tBody:        src,\n\t\t\tContentType: oss.Ptr(contentType),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to upload file to OSS: %w\", err)\n\t\t}\n\t}\n\n\treturn fmt.Sprintf(\"oss://%s/%s\", s.bucketName, objectName), nil\n}\n\n// SaveBytes saves bytes data to OSS.\n// If temp is true and temp bucket is configured, saves to temp bucket.\n// Otherwise saves to main bucket.\nfunc (s *ossFileService) SaveBytes(ctx context.Context, data []byte, tenantID uint64, fileName string, temp bool) (string, error) {\n\tsafeName, err := utils.SafeFileName(fileName)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid file name: %w\", err)\n\t}\n\text := filepath.Ext(safeName)\n\n\ttargetBucket := s.bucketName\n\tclient := s.client","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/file/oss.go#L192-L228","documentation":"This error is returned by ossFileService.SaveFile when the simple (single-request) PutObject call to Alibaba Cloud OSS fails. It wraps the SDK error so callers can inspect the root cause. It is the non-multipart branch of SaveFile, used for smaller files or when the caller's reader fits a single request.","triggerScenarios":"Calling SaveFile with content under the multipart threshold and client.PutObject fails: invalid credentials, bucket does not exist, no PutObject permission, request body read error from src, or network failure before/during the PUT.","commonSituations":"Misconfigured bucket name in config/env; OSS endpoint region mismatch (bucket in cn-hangzhou, client pointed at another region); antivirus/permission tools locking the source file; SDK credentials expired (signature-time errors).","solutions":["Unwrap the error to read the OSS error code (e.g., AccessDenied, NoSuchBucket, SignatureDoesNotMatch).","Validate s.bucketName and endpoint configuration match the actual bucket region.","Verify RAM policy grants oss:PutObject on the target key prefix.","Confirm credentials/STS tokens are current.","Check that src is readable and not already consumed (a drained reader causes body errors)."],"exampleFix":"// before\n_, err = s.client.PutObject(ctx, &oss.PutObjectRequest{...})\nif err != nil {\n    return \"\", fmt.Errorf(\"failed to upload file to OSS: %w\", err)\n}\n// after\nif err != nil {\n    logger.Errorf(ctx, \"OSS PutObject failed bucket=%s key=%s: %v\", s.bucketName, objectName, err)\n    return \"\", fmt.Errorf(\"failed to upload file to OSS: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if s.bucketName == \"\" { return errors.New(\"OSS bucket not configured\") }\nif fi, err := os.Stat(localPath); err != nil || fi.Size() == 0 { return fmt.Errorf(\"source unreadable: %w\", err) }","typeGuard":null,"tryCatchPattern":"path, err := svc.SaveFile(ctx, src, tenantID, name, ctype, false)\nvar svcErr *oss.ServiceError\nif errors.As(err, &svcErr) {\n    switch svcErr.Code {\n    case \"AccessDenied\": // fix RAM permissions\n    case \"NoSuchBucket\": // fix bucket config\n    case \"SignatureDoesNotMatch\": // fix credentials\n    }\n}","preventionTips":["Keep bucket name and endpoint region consistent in configuration.","Rotate and test credentials before expiry.","Ensure the src reader is fresh and not already consumed.","Grant oss:PutObject to the service role on the target prefix.","Log the unwrapped OSS error code for fast diagnosis."],"tags":["oss","upload","putobject","alibaba-cloud","network"],"backgroundTag":"oss-upload-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}