gofr-dev/gofr · error
%w (got: %d)
Error message
%w (got: %d)
What it means
NewRangeReader rejects a negative offset because FTP byte ranges must be non-negative. The library returns errInvalidOffset including the offending value via "(got: %d)". This is a pure caller-input validation error raised before any network I/O.
Source
Thrown at pkg/gofr/datasource/file/ftp/storage_adapter.go:121
if err != nil {
if isFTPNotFoundError(err) {
return nil, fmt.Errorf("%w %q: %w", errObjectNotFound, name, err)
}
return nil, fmt.Errorf("%w for %q: %w", errFailedToCreateReader, name, err)
}
return reader, nil
}
// NewRangeReader creates a range reader for the given object.
func (s *storageAdapter) NewRangeReader(_ context.Context, name string, offset, length int64) (io.ReadCloser, error) {
if name == "" {
return nil, errEmptyObjectName
}
if offset < 0 {
return nil, fmt.Errorf("%w (got: %d)", errInvalidOffset, offset)
}
if s.conn == nil {
return nil, errFTPClientNotInitialized
}
objectPath := s.buildPath(name)
reader, err := s.conn.RetrFrom(objectPath, uint64(offset))
if err != nil {
if isFTPNotFoundError(err) {
return nil, fmt.Errorf("%w %q: %w", errObjectNotFound, name, err)
}
return nil, fmt.Errorf("%w for %q at offset %d: %w", errFailedToCreateReader, name, offset, err)
}
// FTP doesn't support length limit in RetrFrom, so wrap in LimitReaderView on GitHub (pinned to 187eb24962)
Solutions
- Clamp the offset to 0 before calling: if offset < 0 { offset = 0 }
- For tail reads, first StatObject to get the size and compute offset = size - n
- Check the caller's offset computation for underflow (e.g. size - n when n > size)
Example fix
// before
r, err := store.NewRangeReader(ctx, "log.txt", -1024, 1024)
// after
info, _ := store.StatObject(ctx, "log.txt")
offset := info.Size - 1024
if offset < 0 { offset = 0 }
r, err := store.NewRangeReader(ctx, "log.txt", offset, 1024) Defensive patterns
Strategy: validation
Validate before calling
if offset < 0 {
return errors.New("offset must be >= 0")
}
if length < 0 {
length = 0 // read to EOF
} Try / catch
r, err := store.NewRangeReader(ctx, name, offset, length)
if err != nil && strings.Contains(err.Error(), "invalid offset") {
offset = 0
r, err = store.NewRangeReader(ctx, name, offset, length)
} Prevention
- Clamp computed offsets (size-n) to 0 to avoid underflow
- Never use -1 as a sentinel for 'read from end'; StatObject first
- Validate offset/length at your API boundary before calling the adapter
When it happens
Trigger: Calling storageAdapter.NewRangeReader(ctx, name, offset, length) with offset < 0 (e.g. -1 used as a sentinel for 'read from end' or an uninitialized int64).
Common situations: Passing -1 to mean 'tail of file' (not supported here), arithmetic underflow when computing offsets from sizes, uninitialized offset variables.
Related errors
- invalid FTP configuration: host and port are required
- invalid FTP provider
- object name is empty
- invalid offset: must be >= 0
- source and destination names cannot be empty
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/440ac02a6034a34e.
Report an issue: GitHub.