hyperledger/fabric · error

id cannot be nil if buf is not nil

Error message

id cannot be nil if buf is not nil

What it means

PutChaincodeToFS also requires ccpack.id to be non-nil whenever buf is set. The id is the package hash computed by getCDSData during initialization; nil means the initialization did not compute the package identity. This guard prevents writing packages whose hash was never derived.

Source

Thrown at core/common/ccprovider/sigcdspackage.go:286

	if err != nil {
		return nil, nil, err
	}

	if _, err = ccpack.InitFromBuffer(buf); err != nil {
		return nil, nil, err
	}

	return ccpack.buf, ccpack.depSpec, nil
}

// PutChaincodeToFS - serializes chaincode to a package on the file system
func (ccpack *SignedCDSPackage) PutChaincodeToFS() error {
	if ccpack.buf == nil {
		return errors.New("uninitialized package")
	}

	if ccpack.id == nil {
		return errors.New("id cannot be nil if buf is not nil")
	}

	if ccpack.sDepSpec == nil || ccpack.depSpec == nil {
		return errors.New("depspec cannot be nil if buf is not nil")
	}

	if ccpack.env == nil {
		return errors.New("env cannot be nil if buf and depspec are not nil")
	}

	if ccpack.data == nil {
		return errors.New("nil data")
	}

	if ccpack.datab == nil {
		return errors.New("nil data bytes")
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Initialize the package through the standard path (GetCCPackage / InitFromBuffer) so id is computed via getCDSData
  2. Do not set ccpack.buf manually without also computing id
  3. Fix error handling so failed initialization never reaches the write step

Example fix

// before
ccpack.buf = buf // id left nil
ccpack.PutChaincodeToFS()
// after
ccpack := &SignedCDSPackage{}
ccpack.InitFromBuffer(buf) // computes id via getCDSData
ccpack.PutChaincodeToFS()
Defensive patterns

Strategy: type-guard

Validate before calling

func hasComputedID(buf []byte) bool {
    // id must come from a successful init/getCDSData, not manual assignment
    return len(buf) > 0 // pre-check; real id check requires init
}
// Prefer: init then check GetId() error before persisting.

Type guard

func fullyInit(ccpack *ccprovider.SignedCDSPackage) bool {
    _, _, err := ccpack.GetDepSpec()
    return err == nil // GetDepSpec errors when id/buf/depSpec are unset
}

Try / catch

if _, err := ccpack.InitFromBuffer(buf); err != nil {
    return err // ensures id computed via getCDSData
}
if err := ccpack.PutChaincodeToFS(); err != nil {
    if strings.Contains(err.Error(), "id cannot be nil") { return errors.New("package id never computed; use standard init") }
    return err
}

Prevention

When it happens

Trigger: PutChaincodeToFS on a package where buf was set but id was never computed — e.g. fields populated manually or an init path that skipped getCDSData.

Common situations: Hand-assembling SignedCDSPackage structs in custom tooling; partial initialization after an earlier error was swallowed; fabric version changes altering the init flow.

Related errors


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