Tencent/WeKnora · error

failed to copy file in OSS: %w

Error message

failed to copy file in OSS: %w

What it means

This error is returned by ossFileService.CopyFile when the client.CopyObject (server-side copy) call to Alibaba Cloud OSS fails. The parse and key-validation steps already succeeded, so this indicates an OSS-level problem: permissions, object absence, size limits, or network. The SDK error is wrapped and preserved for inspection.

Source

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

	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)
	}

	ext := filepath.Ext(srcPath)
	destKey := fmt.Sprintf("%s%d/%s/%s%s", s.pathPrefix, tenantID, knowledgeID, uuid.New().String(), ext)

	_, err = s.client.CopyObject(ctx, &oss.CopyObjectRequest{
		Bucket:       oss.Ptr(s.bucketName),
		Key:          oss.Ptr(destKey),
		SourceBucket: oss.Ptr(srcBucket),
		SourceKey:    oss.Ptr(srcKey),
	})
	if err != nil {
		return "", fmt.Errorf("failed to copy file in OSS: %w", err)
	}

	newPath := fmt.Sprintf("oss://%s/%s", s.bucketName, destKey)
	logger.Infof(ctx, "Copied OSS object %s to %s", srcPath, newPath)
	return newPath, nil
}

// GetFile retrieves a file from OSS by its path.
func (s *ossFileService) GetFile(ctx context.Context, filePath string) (io.ReadCloser, error) {
	bucketName, objectName, err := parseOssFilePath(filePath)
	if err != nil {
		return nil, err
	}
	if err := utils.SafeObjectKey(objectName); err != nil {
		return nil, fmt.Errorf("invalid file path: %w", err)
	}

	var client *oss.Client

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Unwrap the error and check for NoSuchKey — the source object may be gone; verify it exists with a HeadObject first.
  2. Verify RAM permissions: oss:GetObject on the source bucket/key and oss:PutObject on the destination.
  3. For sources >5 GB, use multipart (UploadPartCopy) instead of CopyObject.
  4. Confirm source and destination buckets are compatible (region/storage class) for direct copy.
  5. Retry on transient 5xx/network errors with backoff.

Example fix

// before
_, err = s.client.CopyObject(ctx, &oss.CopyObjectRequest{...})
if err != nil {
    return "", fmt.Errorf("failed to copy file in OSS: %w", err)
}
// after
if err != nil {
    var respErr *oss.ServiceError
    if errors.As(err, &respErr) && respErr.Code == "NoSuchKey" {
        return "", fmt.Errorf("source object missing: %w", err)
    }
    return "", fmt.Errorf("failed to copy file in OSS: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight before CopyFile
srcBucket, srcKey, err := parseOssFilePath(srcPath)
if err != nil { return ErrCrossBackendCopy }
if err := utils.SafeObjectKey(srcKey); err != nil { return err }
_, err = client.HeadObject(ctx, &oss.HeadObjectRequest{Bucket: oss.Ptr(srcBucket), Key: oss.Ptr(srcKey)})
// err != nil here means the source object is missing -> skip copy

Try / catch

newPath, err := svc.CopyFile(ctx, srcPath, tenantID, knowledgeID)
var svcErr *oss.ServiceError
if errors.As(err, &svcErr) {
    switch svcErr.Code {
    case "NoSuchKey": // source gone -> treat as not found
    case "AccessDenied": // fix IAM on source/destination
    default: if isTransient(svcErr.Code) { /* retry */ }
    }
}

Prevention

When it happens

Trigger: Calling CopyFile with a valid oss:// source where the CopyObject API fails: source object does not exist (NoSuchKey), missing oss:GetObject on source or oss:PutObject on destination, source object larger than the 5 GB CopyObject limit, cross-region/cross-storage-class copy restrictions, or network errors.

Common situations: Copying a knowledge file whose row was deleted from OSS but still referenced in the DB; RAM policies granting destination write but not source read; very large attachments exceeding server-side copy limits (require multipart copy); buckets in different regions.

Related errors


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