Tencent/WeKnora · error · ErrCrossBackendCopy

oss copy rejected source %q: %w

Error message

oss copy rejected source %q: %w

What it means

This error is returned by ossFileService.CopyFile when the srcPath is not a valid oss:// URL, i.e., parseOssFilePath fails. The service wraps it together with the sentinel error ErrCrossBackendCopy to signal that this backend cannot handle the given source path. Callers should route the file to the matching backend service instead of forcing a copy through the OSS implementation.

Source

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

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

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

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Check srcPath starts with oss:// before calling CopyFile.
  2. If ErrCrossBackendCopy is returned, dispatch to the file service matching the path's scheme instead.
  3. Fix data sources that persist legacy paths without the backend scheme.
  4. Normalize stored file paths to scheme-qualified URIs at write time.

Example fix

// before
newPath, err := ossSvc.CopyFile(ctx, srcPath, tenantID, knowledgeID)
// after
if !strings.HasPrefix(srcPath, "oss://") {
    return ErrCrossBackendCopy
}
newPath, err := ossSvc.CopyFile(ctx, srcPath, tenantID, knowledgeID)
Defensive patterns

Strategy: validation

Validate before calling

// before calling CopyFile
if !strings.HasPrefix(srcPath, "oss://") {
    return fmt.Errorf("%w: not an oss path: %s", ErrCrossBackendCopy, srcPath)
}

Type guard

func isOSSPath(p string) bool { return strings.HasPrefix(p, "oss://") }

Try / catch

newPath, err := svc.CopyFile(ctx, srcPath, tenantID, knowledgeID)
if errors.Is(err, ErrCrossBackendCopy) {
    // route to the backend matching srcPath's scheme instead
}

Prevention

When it happens

Trigger: Calling CopyFile with srcPath that lacks the oss:// scheme prefix (e.g., s3://bucket/key, /local/path/file, or an empty string), so parseOssFilePath returns 'invalid OSS file path'.

Common situations: Multi-backend deployments where a file was originally stored in S3/MinIO/COS but the OSS service is invoked generically; refactors that dropped the scheme prefix; DB rows storing legacy absolute paths instead of backend URIs.

Related errors


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