hyperledger/fabric · error

no object open, cannot close object

Error message

no object open, cannot close object

What it means

API-misuse guard on JSONFileWriter.CloseObject: CloseObject was called when no object is open (objectOpened is false, either never opened or already closed). This is a client-side state-machine error, not an I/O failure.

Source

Thrown at internal/ledgerutil/jsonrw/json_read_write.go:93

// Open a json object
func (w *JSONFileWriter) OpenObject() error {
	if w.objectOpened {
		return errors.Errorf("object already open, must close object before starting a new one")
	}

	w.objectOpened = true
	_, err := w.buffer.Write([]byte("{\n"))
	if err != nil {
		return err
	}

	return nil
}

// Close a json object
func (w *JSONFileWriter) CloseObject() error {
	if !w.objectOpened {
		return errors.Errorf("no object open, cannot close object")
	}

	_, err := w.buffer.Write([]byte("}\n"))
	if err != nil {
		return err
	}

	w.objectOpened = false
	w.firstFieldWritten = false

	return nil
}

// Add field to an open json object
func (w *JSONFileWriter) AddField(k string, v any) error {
	// Need to open object before adding fields
	if !w.objectOpened {
		return errors.Errorf("no object open, cannot add field")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Balance every OpenObject with exactly one CloseObject
  2. Only call CloseObject if OpenObject returned nil
  3. Track whether the object was opened in a local bool before cleanup code

Example fix

// before
w.OpenObject()
w.CloseObject()
w.CloseObject() // second call errors
// after
w.OpenObject()
w.CloseObject()
Defensive patterns

Strategy: validation

Validate before calling

if objectWasOpened && !objectWasClosed {
	if err := w.CloseObject(); err != nil { return err }
}

Type guard

func objectNeedsClose(opened, closed bool) bool { return opened && !closed }

Try / catch

if err := w.CloseObject(); err != nil {
	return fmt.Errorf("close object: %w", err)
}

Prevention

When it happens

Trigger: Calling CloseObject on a fresh writer, after the object was already closed, or after an OpenObject call failed with an error.

Common situations: Unbalanced open/close calls in error-handling paths, duplicated cleanup code, or ignoring the error from OpenObject and proceeding anyway.

Related errors


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