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

After confirming ccpack.buf is non-nil, PutChaincodeToFS checks ccpack.id, the package hash/id computed during initialization. A non-nil buffer with a nil id means the package bytes exist but the identity/hash was never derived, so the library refuses to write a package whose id cannot be verified.

Source

Thrown at core/common/ccprovider/cdspackage.go:232

		return nil, nil, err
	}

	return ccpack.buf, ccpack.depSpec, nil
}

// InitFromFS returns the chaincode and its package from the file system
func (ccpack *CDSPackage) InitFromFS(ccNameVersion string) ([]byte, *pb.ChaincodeDeploymentSpec, error) {
	return ccpack.InitFromPath(ccNameVersion, chaincodeInstallPath)
}

// PutChaincodeToFS - serializes chaincode to a package on the file system
func (ccpack *CDSPackage) 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.depSpec == nil {
		return errors.New("depspec cannot be nil if buf is not nil")
	}

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

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

	ccname := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Name
	ccversion := ccpack.depSpec.ChaincodeSpec.ChaincodeId.Version

	// return error if chaincode exists

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Populate the package through the normal flow: InitFromBuffer or InitFromPath, which set buf, id, depSpec, data, and datab together.
  2. If constructing manually, use PutChaincodeDepSpec with a computed hash (ccprovider.GetHash for the bytes) so ccpack.id is set before writing.
  3. Regenerate the package from the original ChaincodeDeploymentSpec instead of patching fields individually.

Example fix

// before
ccpack := &CDSPackage{buf: buf} // id never computed
ccpack.PutChaincodeToFS() // -> "id cannot be nil if buf is not nil"

// after
ccpack := &CDSPackage{}
if err := ccpack.InitFromBuffer(buf); err != nil {
    return err
}
ccpack.PutChaincodeToFS()
Defensive patterns

Strategy: validation

Validate before calling

if ccpack.buf != nil && ccpack.id == nil {
    return errors.New("package id missing: re-run InitFromBuffer to compute hash")
}

Type guard

func hasID(p *ccprovider.CDSPackage) bool {
    return p != nil && p.buf != nil && p.id != nil
}

Try / catch

if err := ccpack.PutChaincodeToFS(); err != nil {
    if strings.Contains(err.Error(), "id cannot be nil") {
        return fmt.Errorf("package not fully initialized: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling PutChaincodeToFS on a CDSPackage where buf was set directly (or via an init path that skipped id computation) but InitFromBuffer/InitFromPath never populated ccpack.id — e.g. a custom or partially-copied CDSPackage struct.

Common situations: Hand-assembling a CDSPackage with only buf set; copying a package struct field-by-field and dropping the id; a forked or patched init routine that deserializes the depspec but skips PutChaincodeDepSpec's id assignment.

Related errors


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