hyperledger/fabric · error
object already open, must close object before starting a new
Error message
object already open, must close object before starting a new one
What it means
JSONFileWriter serializes one top-level JSON object field at a time, tracking nesting with an objectOpened flag. OpenObject throws if an object is already open, because JSON cannot nest a bare '{' without a field and the writer enforces open/close discipline.
Source
Thrown at internal/ledgerutil/jsonrw/json_read_write.go:78
func NewJSONFileWriter(filePath string) (*JSONFileWriter, error) {
f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0o644)
if err != nil {
return nil, err
}
b := bufio.NewWriter(f)
return &JSONFileWriter{
file: f,
buffer: b,
encoder: json.NewEncoder(b),
}, nil
}
// 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"))View on GitHub (pinned to 2736b63f8f)
Solutions
- Call CloseObject before each new OpenObject
- Move OpenObject out of loops that iterate multiple times
- Check error returns of CloseObject so an early return does not leave the object open
- Restructure code to open/close per item inside the loop rather than around it
Example fix
// before
w.OpenObject()
for _, v := range items { w.OpenObject() }
// after
for _, v := range items {
w.OpenObject()
w.AddField("key", v)
w.CloseObject()
} Defensive patterns
Strategy: validation
Validate before calling
type openTracker struct{ objOpen, listOpen bool } Type guard
func canOpenObject(w *jsonrw.JSONFileWriter, tracked bool) bool { return !tracked } Try / catch
if err := w.OpenObject(); err != nil {
return fmt.Errorf("open object: %w", err)
}
defer func() {
if err := w.CloseObject(); err != nil { log.Error(err) }
}() Prevention
- Pair every OpenObject with a CloseObject immediately via defer
- Never place OpenObject inside loops
- Check OpenObject/CloseObject return values instead of ignoring errors
- Track open state in a local variable when writing complex nested output
When it happens
Trigger: Calling OpenObject twice without an intervening CloseObject on the same JSONFileWriter.
Common situations: Loop refactoring bugs where OpenObject is inside a loop instead of outside it, or a forgotten CloseObject on an early-return path.
Related errors
- no object open, cannot close object
- list already open, must close list before starting a new one
- no list open, cannot close list
- no object open, cannot add field
- no list open, cannot add entries
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2b1c20592a5c3a31.
Report an issue: GitHub.