Tencent/WeKnora · error

failed to delete file: %w

Error message

failed to delete file: %w

What it means

DeleteFile wraps errors from the S3 DeleteObject call. It indicates the delete request itself failed — permissions, connectivity, or bucket state — not that the object didn't exist (S3 delete of a missing key succeeds). The original S3 error is chained via %w.

Source

Thrown at internal/application/service/file/s3.go:286

		return nil, fmt.Errorf("failed to get file from S3: %w", err)
	}

	return resp.Body, nil
}

// DeleteFile deletes a file
func (s *s3FileService) DeleteFile(ctx context.Context, filePath string) error {
	objectName, err := s.parseS3FilePath(filePath)
	if err != nil {
		return err
	}

	_, err = s.client.DeleteObject(ctx, &s3.DeleteObjectInput{
		Bucket: aws.String(s.bucketName),
		Key:    aws.String(objectName),
	})
	if err != nil {
		return fmt.Errorf("failed to delete file: %w", err)
	}

	return nil
}

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

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

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Grant s3:DeleteObject on the bucket/prefix in the IAM policy
  2. Check for Object Lock, retention policies, or deny statements in bucket policy
  3. Unwrap with errors.As to read the exact S3 error code and act on it
  4. Verify endpoint/region and network reachability from the host

Example fix

// before
err := fileSvc.DeleteFile(ctx, path)
// after
err := fileSvc.DeleteFile(ctx, path)
if err != nil {
    var apiErr smithy.APIError
    if errors.As(err, &apiErr) && apiErr.ErrorCode() == "AccessDenied" {
        // log config/permission issue, don't retry
    }
    return err
}
Defensive patterns

Strategy: try-catch

Try / catch

err := svc.DeleteFile(ctx, path)
if err != nil {
    var apiErr smithy.APIError
    if errors.As(err, &apiErr) {
        log.Printf("delete failed code=%s: %v", apiErr.ErrorCode(), err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling DeleteFile when IAM credentials lack s3:DeleteObject on the bucket, the bucket has versioning with Object Lock / legal hold preventing deletion, or the S3 endpoint is unreachable.

Common situations: Read-only IAM role used by the service; S3 Object Lock or bucket policy denying DeleteObject; misconfigured endpoint; KMS key permission missing for SSE-KMS objects.

Related errors


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