Tencent/WeKnora · error

failed to upload bytes to OSS: %w

Error message

failed to upload bytes to OSS: %w

What it means

This error is returned by ossFileService.SaveBytes when the PutObject call uploading the byte slice to OSS fails. It wraps the SDK error, so the OSS-level cause (auth, permissions, network, quota) is preserved. The content type is derived from the file extension via utils.GetContentTypeByExt before upload.

Source

Thrown at internal/application/service/file/oss.go:244

	targetBucket := s.bucketName
	client := s.client
	objectName := fmt.Sprintf("%s%d/exports/%s%s", s.pathPrefix, tenantID, uuid.New().String(), ext)

	if temp && s.tempClient != nil {
		targetBucket = s.tempBucketName
		client = s.tempClient
		objectName = fmt.Sprintf("exports/%d/%s%s", tenantID, uuid.New().String(), ext)
	}

	_, err = client.PutObject(ctx, &oss.PutObjectRequest{
		Bucket:      oss.Ptr(targetBucket),
		Key:         oss.Ptr(objectName),
		Body:        bytes.NewReader(data),
		ContentType: oss.Ptr(utils.GetContentTypeByExt(ext)),
	})
	if err != nil {
		return "", fmt.Errorf("failed to upload bytes to OSS: %w", err)
	}

	return fmt.Sprintf("oss://%s/%s", targetBucket, objectName), nil
}

// CopyFile copies an existing OSS object to a new knowledge-owned object using a
// server-side CopyObject (no data leaves OSS). The destination uses the same
// layout as SaveFile. Returns ErrCrossBackendCopy when srcPath is not an oss:// path.
func (s *ossFileService) CopyFile(ctx context.Context,
	srcPath string, tenantID uint64, knowledgeID string,
) (string, error) {
	srcBucket, srcKey, err := parseOssFilePath(srcPath)
	if err != nil {
		return "", fmt.Errorf("oss copy rejected source %q: %w", srcPath, ErrCrossBackendCopy)
	}
	if err := utils.SafeObjectKey(srcKey); err != nil {
		return "", fmt.Errorf("invalid source path: %w", err)
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Unwrap the error to identify the OSS error code.
  2. Verify target bucket (main vs temp bucket when temp=true) exists and credentials have write access.
  3. Check network/endpoint configuration for the region the bucket lives in.
  4. For very large payloads, reduce size or add multipart support / compression before upload.
  5. Retry transient failures (RequestTimeout, 5xx) with backoff.

Example fix

// before
if err != nil {
    return "", fmt.Errorf("failed to upload bytes to OSS: %w", err)
}
// after
if err != nil {
    var retriable bool
    var netErr net.Error
    if errors.As(err, &netErr) { retriable = true }
    return "", fmt.Errorf("failed to upload bytes to OSS (retriable=%v): %w", retriable, err)
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-checks before SaveBytes
if len(data) == 0 { return errors.New("empty payload") }
if temp && tempBucketName == "" { return errors.New("temp bucket not configured") }

Try / catch

path, err := svc.SaveBytes(ctx, data, tenantID, name, temp)
var svcErr *oss.ServiceError
if errors.As(err, &svcErr) {
    if isRetryableCode(svcErr.Code) { // RequestTimeout, InternalError, 5xx
        // retry with backoff
    }
}

Prevention

When it happens

Trigger: Calling SaveBytes with valid data but client.PutObject fails: expired credentials, missing oss:PutObject on the target bucket (main or temp bucket), network failure, bucket missing, or payload exceeding OSS/SDK size limits for a single PUT.

Common situations: Temp-bucket misconfiguration (SaveBytes with temp=true targeting a nonexistent temp bucket); oversized in-memory exports exceeding single-PUT limits; key rotation invalidating credentials mid-run; egress firewall rules blocking OSS endpoints.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/7e73166b4bb765ec. Report an issue: GitHub.