gofr-dev/gofr · error

failed to delete object

Error message

failed to delete object

What it means

errFailedToDeleteObject is returned by DeleteObject when the DELE (or directory removal) command fails after the object was confirmed to exist. It wraps the server-side error, meaning the server refused or could not complete the deletion.

Source

Thrown at pkg/gofr/datasource/file/ftp/storage_adapter.go:29

	"time"

	"github.com/jlaffaye/ftp"
	"gofr.dev/pkg/gofr/datasource/file"
)

var (
	// Storage adapter errors.
	errFTPConfigNil            = errors.New("FTP config is nil")
	errFTPClientNotInitialized = errors.New("FTP client is not initialized")
	errEmptyObjectName         = errors.New("object name is empty")
	errInvalidOffset           = errors.New("invalid offset: must be >= 0")
	errEmptySourceOrDest       = errors.New("source and destination names cannot be empty")
	errSameSourceAndDest       = errors.New("source and destination are the same")
	errFailedToCreateReader    = errors.New("failed to create reader")
	errFailedToCreateWriter    = errors.New("failed to create writer")
	errObjectNotFound          = errors.New("object not found")
	errFailedToGetObjectAttrs  = errors.New("failed to get object attrs")
	errFailedToDeleteObject    = errors.New("failed to delete object")
	errFailedToListObjects     = errors.New("failed to list objects")
	errFailedToListDirectory   = errors.New("failed to list directory")
	errWriterAlreadyClosed     = errors.New("writer already closed")
	errFTPConfigInvalid        = errors.New("invalid FTP configuration: host and port are required")
)

// Config represents the FTP configuration.
type Config struct {
	Host        string        // FTP server hostname
	User        string        // FTP username
	Password    string        // FTP password
	Port        int           // FTP port
	RemoteDir   string        // Remote directory path. Base Path for all FTP Operations.
	DialTimeout time.Duration // FTP connection timeout
}

// storageAdapter adapts FTP client to implement file.StorageProvider.
type storageAdapter struct {

View on GitHub (pinned to 187eb24962)

Solutions

  1. Check the FTP user has write/delete permission on the parent directory
  2. For directories, empty them (delete children first) before removal
  3. Inspect the wrapped error for the server reply code to confirm the cause
  4. Retry if the object may have been concurrently removed by another process
Defensive patterns

Strategy: validation

Validate before calling

// check permissions/emptiness before delete
info, err := fs.StatObject(ctx, name)
if err != nil { return err }
_ = info // verify it is a deletable file, and dir is empty if removing a directory

Type guard

func isDeleteError(err error) bool { return errors.Is(err, ftp.ErrFailedToDeleteObject) }

Try / catch

err := fs.DeleteObject(ctx, name)
if errors.Is(err, ftp.ErrFailedToDeleteObject) {
    // inspect wrapped server reply; check perms or non-empty dir
    return fmt.Errorf("delete %s: %w", name, err)
}

Prevention

When it happens

Trigger: Calling DeleteObject on a path that exists but cannot be removed: read-only permissions, the path is a non-empty directory, or the server rejects the DELE/RMD command.

Common situations: FTP account lacks delete permission; attempting to delete a directory that still contains entries; file locked by another upload session; object vanished between stat and delete (race).

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/c4c8fe1339fd0426. Report an issue: GitHub.