gofr-dev/gofr · error
errFileNotOpenForReading
errFileNotOpenForReading
Error message
file not open for reading
What it means
A sentinel error from the common file layer: the file handle was opened without read intent (openFlags lacked read), so Read/ReadAll refuse to operate. It prevents silently reading an empty stream from a write-only handle.
Source
Thrown at pkg/gofr/datasource/file/common_file.go:18
package file
import (
"context"
"errors"
"fmt"
"io"
"os"
"strings"
"time"
"gofr.dev/pkg/gofr/datasource"
)
// Error variables for common file operations.
var (
// errFileNotOpenForReading is returned when attempting to read from a file that wasn't opened for reading.
errFileNotOpenForReading = errors.New("file not open for reading")
// errFileNotOpenForWriting is returned when attempting to write to a file that wasn't opened for writing.
errFileNotOpenForWriting = errors.New("file not open for writing")
// errWriteAtNotSupported is returned when WriteAt is called on cloud storage.
errWriteAtNotSupported = errors.New("WriteAt not supported for cloud storage")
// errWriterNil is returned when NewWriter returns nil.
errWriterNil = errors.New("NewWriter returned nil")
)
// File permission constants.
const (
// DefaultFileMode is the standard file permission (0644 = rw-r--r--).
DefaultFileMode os.FileMode = 0644
// DefaultDirMode is the standard directory permission (0755 = rwxr-xr-x).
DefaultDirMode os.FileMode = 0755View on GitHub (pinned to 187eb24962)
Solutions
- Reopen the file in read mode (or read+write flags if supported by the adapter) before calling Read/ReadAll.
- Check the file's open mode / read flag before reading, and fail fast with a clear message.
- Use WriteAt/Write for output handles and a separate Open() call for reading back content.
Example fix
// before f, _ := store.Create(ctx, "out.txt") f.ReadAll(ctx) // error: file not open for reading // after f, _ := store.Open(ctx, "out.txt") data, err := f.ReadAll(ctx)
Defensive patterns
Strategy: validation
Validate before calling
func canRead(f interface{ Read(context.Context, []byte) (int, error) }, openedForRead bool) error {
if !openedForRead {
return errors.New("handle not opened for reading: reopen via Open() before Read/ReadAll")
}
return nil
} Try / catch
data, err := f.ReadAll(ctx)
if err != nil && errors.Is(err, datasource.ErrFileNotOpenForReading) {
f, err = store.Open(ctx, path) // reopen in read mode
if err != nil { return err }
data, err = f.ReadAll(ctx)
} Prevention
- Open with read intent (Open) whenever you plan to call Read/ReadAll.
- Treat Create/Append handles as write-only in this abstraction.
- Track the open mode alongside handles and assert before read calls.
- After writes, close and reopen the file to read content back.
When it happens
Trigger: Calling Read or ReadAll on a file obtained via Create/AppendMode or opened with write-only flags in common_file.go, rather than via an Open/read-enabled handle.
Common situations: Opening a cloud file for append/write then trying to read back what was written without reopening; Copy-on-write patterns forgetting to reopen with read; misunderstanding that write-mode handles in this abstraction don't also grant read.
Related errors
- %w: S3 file is empty
- response retrieved is nil
- s3 backend did not honor the requested byte range
- %w: negative offset %d
- input should be a pointer to a string
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/ece0f8d9a4e31cc9.
Report an issue: GitHub.