gofr-dev/gofr · error

FTP client is not initialized

Error message

FTP client is not initialized

What it means

errFTPClientNotInitialized is returned by adapter operations (NewReader, NewRangeReader, NewWriter, DeleteObject, CopyObject, StatObject) when the internal FTP client has not been connected yet. Operations require a live *ftp.ServerConn obtained during Connect; without it the adapter cannot talk to the server.

Source

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

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"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

View on GitHub (pinned to 187eb24962)

Solutions

  1. Call fs.Connect() and wait until IsConnected() is true (or connection-ready signal) before performing file operations.
  2. Check the connection state before each operation and re-Connect if needed.
  3. Inspect Connect logs for the initial failure (bad host/credentials) that prevented client initialization.

Example fix

// before
fs := ftp.New(cfg)
r, err := fs.Open("file.txt") // client not initialized
// after
fs := ftp.New(cfg)
fs.Connect()
// wait for connection / check IsConnected()
r, err := fs.Open("file.txt")
Defensive patterns

Strategy: validation

Validate before calling

func (a *App) withFTP(op func(fs file.FileSystemProvider) error) error {
    if !a.ftpConnected.Load() { return fmt.Errorf("ftp not connected") }
    return op(a.fs)
}

Type guard

func connected(fs *file.CommonFileSystem) bool { return fs.IsConnected() }

Try / catch

if !fs.IsConnected() {
    fs.Connect()
    // wait/subscribe for ready before proceeding
}
if err := op(ctx, fs); err != nil {
    // re-Connect and retry once on transport failures
}

Prevention

When it happens

Trigger: Calling any object operation before Connect() succeeds, or after a failed/dropped connection left the client nil; also returned by TestStorageAdapter-type paths where the client was never set.

Common situations: Using the filesystem immediately after New without waiting for connection; background retry still in progress after the first Connect failure; server disconnect invalidated and nulled the client.

Related errors


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