Tencent/WeKnora · error

failed to delete file from OBS: %w

Error message

failed to delete file from OBS: %w

What it means

DeleteFile wraps the error from s3 DeleteObject when the OBS delete call fails. Note S3-compatible DeleteObject often returns success even for a missing key, so this error usually reflects transport/permission problems rather than the object not existing.

Source

Thrown at internal/application/service/file/obs.go:219

	if err != nil {
		return nil, fmt.Errorf("failed to get file from OBS: %w", err)
	}

	return output.Body, nil
}

func (s *obsFileService) DeleteFile(ctx context.Context, filePath string) error {
	objectKey, err := s.parseObsFilePath(filePath)
	if err != nil {
		return err
	}

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

	return nil
}

func (s *obsFileService) GetFileURL(ctx context.Context, filePath string) (string, error) {
	if strings.HasPrefix(filePath, "http://") || strings.HasPrefix(filePath, "https://") {
		return filePath, nil
	}

	objectKey, err := s.parseObsFilePath(filePath)
	if err != nil {
		return "", err
	}

	if s.proxyDomain != "" {
		return s.proxyDomain + "/" + strings.TrimPrefix(objectKey, "/"), nil
	}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Unwrap and classify: AccessDenied → fix IAM permissions; network errors → retry with backoff
  2. Verify the credentials used by the OBS service include delete permission
  3. Confirm bucketName/endpoint config matches the bucket that owns the file
  4. If delete is part of a saga/cleanup, log the wrapped error and mark the record for later garbage collection instead of failing the whole transaction

Example fix

// before
if err != nil { return fmt.Errorf("failed to delete file from OBS: %w", err) }
// after
if err != nil {
    if isRetryableNetErr(err) {
        return retryBackoff(func() error { return s.DeleteFile(ctx, filePath) }, 3)
    }
    return fmt.Errorf("failed to delete file from OBS: %w", err)
}
Defensive patterns

Strategy: retry

Try / catch

err := svc.DeleteFile(ctx, p)
if err != nil {
    if isRetryableNetErr(err) {
        err = retryBackoff(3, func() error { return svc.DeleteFile(ctx, p) })
    }
    if err != nil {
        log.Warn("obs delete deferred", "path", p, "err", err) // mark for GC
    }
}

Prevention

When it happens

Trigger: Calling DeleteFile when the client cannot reach OBS (network/DNS), credentials lack s3:DeleteObject permission, or the bucket/region configuration is wrong.

Common situations: Read-only IAM policy applied to the deletion job's credentials; network partition between app and OBS; wrong bucket name after config change so the delete goes to a non-existent bucket.

Related errors


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