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
- Grant s3:DeleteObject on the bucket/prefix in the IAM policy
- Check for Object Lock, retention policies, or deny statements in bucket policy
- Unwrap with errors.As to read the exact S3 error code and act on it
- 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
- Grant s3:DeleteObject on the app's prefixes in IAM
- Watch for Object Lock/retention policies on buckets used for deletable files
- Don't retry AccessDenied errors; only retry transient/network errors
- Treat delete of a missing key as success (S3 semantics)
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
- failed to get file from S3: %w
- failed to copy file in S3: %w
- failed to delete file from OBS: %w
- failed to load AWS config: %w
- s3 copy rejected source %q: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/c3a18e652a18184b.
Report an issue: GitHub.