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

  1. Set the store path explicitly, e.g. NewStore(path) with the peer's fileSystemPath + "/lifecycle/chaincodes"
  2. Fix the peer configuration so peer.fileSystemPath is non-empty before instantiating the store
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/c8b44f4019995607. Report an issue: GitHub.