gofr-dev/gofr · error

object not found

Error message

object not found

What it means

errObjectNotFound is returned when the requested object (file or directory) does not exist on the FTP server. StatObject, readers, DeleteObject and CopyObject all use it as the sentinel for a missing path. Callers can test with errors.Is to implement not-found handling.

Source

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

	"path"
	"strings"
	"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
}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Check the exact object path, including case and leading slash
  2. List the parent directory (ListDir/ListObjects) to confirm the object exists
  3. Handle it explicitly: if errors.Is(err, ftp.ErrObjectNotFound) { ... create or skip ... }
  4. Verify the FTP user's home/root — relative paths resolve against it, not the server filesystem root

Example fix

// before
_, err := fs.StatObject(ctx, "Reports/Q4.csv")
// after
_, err := fs.StatObject(ctx, "reports/q4.csv") // correct case per server listing
if errors.Is(err, ftp.ErrObjectNotFound) { /* create it */ }
Defensive patterns

Strategy: type-guard

Validate before calling

// check existence before dependent operations
if _, err := fs.StatObject(ctx, name); errors.Is(err, ftp.ErrObjectNotFound) {
    // object absent — create or skip
}

Type guard

func isNotFound(err error) bool { return errors.Is(err, ftp.ErrObjectNotFound) }

Try / catch

data, err := fs.NewReader(ctx, name)
if errors.Is(err, ftp.ErrObjectNotFound) {
    return nil, ErrMissing // map to application-level not-found
}
if err != nil { return nil, err }

Prevention

When it happens

Trigger: Calling StatObject, NewReader, NewRangeReader, DeleteObject, CopyObject, or the internal statFile/statDirectory helpers with a name that has no matching entry on the server.

Common situations: Typos or case-sensitivity mismatches in the object name (FTP paths are case-sensitive); file deleted by another process; using an absolute path when the session root differs; stale cache of object names.

Related errors


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