hyperledger/fabric · error
empty path not allowed
Error message
empty path not allowed
What it means
FilesystemIO.WriteFile requires a non-empty base directory path because it creates a temporary file inside that directory (os.CreateTemp) before renaming into place. An empty path would be invalid, so it is rejected up front with this sentinel error.
Source
Thrown at core/chaincode/persistence/persistence.go:46
// checking for existence of a specified file
type IOReadWriter interface {
ReadDir(string) ([]os.FileInfo, error)
ReadFile(string) ([]byte, error)
Remove(name string) error
WriteFile(string, string, []byte) error
MakeDir(string, os.FileMode) error
Exists(path string) (bool, error)
}
// FilesystemIO is the production implementation of the IOWriter interface
type FilesystemIO struct{}
// WriteFile writes a file to the filesystem; it does so atomically
// by first writing to a temp file and then renaming the file so that
// if the operation crashes midway we're not stuck with a bad package
func (f *FilesystemIO) WriteFile(path, name string, data []byte) error {
if path == "" {
return errors.New("empty path not allowed")
}
tmpFile, err := os.CreateTemp(path, ".ccpackage.")
if err != nil {
return errors.Wrapf(err, "error creating temp file in directory '%s'", path)
}
defer os.Remove(tmpFile.Name())
if n, err := tmpFile.Write(data); err != nil || n != len(data) {
if err == nil {
err = errors.Errorf(
"failed to write the entire content of the file, expected %d, wrote %d",
len(data), n,
)
}
return errors.Wrapf(err, "error writing to temp file '%s'", tmpFile.Name())
}
if err := tmpFile.Close(); err != nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Set the store path explicitly, e.g. NewStore(path) with the peer's fileSystemPath + "/lifecycle/chaincodes"
- Fix the peer configuration so peer.fileSystemPath is non-empty before instantiating the store
- Add a startup validation that the configured path is non-empty and writable
Example fix
// before
store := &persistence.Store{Path: "", ReadWriter: &persistence.FilesystemIO{}}
// after
store, err := persistence.NewStore("/var/hyperledger/production/lifecycle/chaincodes", &persistence.FilesystemIO{}) Defensive patterns
Strategy: validation
Validate before calling
func ensurePath(p string) error {
if strings.TrimSpace(p) == "" {
return errors.New("chaincode store path must be non-empty")
}
return nil
} Type guard
func validPath(p string) bool { return p != "" } Try / catch
if err := io.WriteFile(path, name, data); err != nil {
if err.Error() == "empty path not allowed" {
return fmt.Errorf("store path not configured: %w", err)
}
return err
} Prevention
- Always obtain the store path from peer configuration (peer.fileSystemPath), never hardcode empty defaults
- Validate configuration at peer startup, before the store is constructed
- In tooling/tests, use NewStore instead of building Store structs by hand
When it happens
Trigger: Invoking WriteFile (directly or via Store.SaveChaincodePackage) with path == "", e.g. a store constructed with Store{Path: ""} or a persistence config where the chaincode install directory was not set.
Common situations: Missing or misparsed configuration for peer.fileSystemPath / chaincode install path; constructing FilesystemIO manually in tests or tooling with an empty Path field.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- failed writing file %s: %v
- %s is mandatory and cannot be empty
- config ID illegal, cannot be empty
- config ID illegal, cannot be longer than %d
- name '%s' for config ID is not allowed
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/c8b44f4019995607.
Report an issue: GitHub.