{"record":{"id":"5f1396541226344e","repo":"canopy-network/canopy","slug":"flush-error-v","errorCode":null,"errorMessage":"flush error: %v","messagePattern":"flush error: (.+?)","errorType":"error_code","errorClass":"ErrCloseDB","httpStatus":null,"severity":"critical","filePath":"store/store.go","lineNumber":622,"sourceCode":"\ts.ss.Close()\n\ts.sc = nil\n\ts.Indexer.db.Close()\n\tif s.writer != nil {\n\t\ts.writer.Close()\n\t}\n}\n\n// Close() discards the writer and closes an owned database connection\nfunc (s *Store) Close() lib.ErrorI {\n\ts.jobs.Wait()\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.Discard()\n\tif !s.ownsDB {\n\t\treturn nil\n\t}\n\tif err := s.db.Flush(); err != nil {\n\t\treturn ErrCloseDB(fmt.Errorf(\"flush error: %v\", err))\n\t}\n\tif err := s.db.Close(); err != nil {\n\t\treturn ErrCloseDB(err)\n\t}\n\treturn nil\n}\n\n// commitIDKey() returns the key for the commitID at a specific version\nfunc (s *Store) commitIDKey(version uint64) []byte {\n\treturn append(stateCommitIDPrefix, lib.JoinLenPrefix(fmt.Appendf(nil, \"%d\", version))...)\n}\n\n// getCommitID() retrieves the CommitID value for the specified version from the database\nfunc (s *Store) getCommitID(version uint64) (id lib.CommitID, err lib.ErrorI) {\n\tvar bz []byte\n\tbz, err = NewTxn(s.Indexer.db.reader, nil, nil, false, false, true).Get(s.commitIDKey(version))\n\tif err != nil {\n\t\treturn","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/store/store.go#L604-L640","documentation":"Store.Close discards any open transaction state and, if the store owns the underlying pebble DB, flushes memtables to disk before closing. If db.Flush() fails (disk error, corruption, I/O failure), the close is aborted with this wrapped error so the caller knows data may not be durable.","triggerScenarios":"Calling Store.Close() (directly or via deferred close in tests/app shutdown) when the underlying pebble Flush returns an error — typically disk-full, permissions, or I/O errors at shutdown.","commonSituations":"Node shutdown while the disk is full or read-only; container filesystem issues; failing disk; closing a store in a test environment with a constrained temp directory.","solutions":["Check the wrapped pebble error for the root cause (disk full, permission denied, corruption)","Free disk space or fix filesystem permissions, then reopen and cleanly close the store again","Check filesystem health (dmesg / SMART) if I/O errors persist","If the error recurs during tests, point the store at a directory with sufficient space"],"exampleFix":"// before\ndefer store.Close() // error swallowed\n// after\nif err := store.Close(); err != nil {\n    log.Fatalf(\"store close failed, data may not be durable: %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"if freeDisk(dataDir) < minHeadroom { return errors.New(\"insufficient disk space to close store cleanly\") }\nif !writable(dataDir) { return errors.New(\"data dir not writable\") }","typeGuard":null,"tryCatchPattern":"if err := st.Close(); err != nil {\n    if strings.Contains(err.Error(), \"flush error\") {\n        log.Fatalf(\"store flush failed on close: %v — check disk space/health before restarting\", err)\n    }\n    return err\n}","preventionTips":["Monitor disk space and alert before it fills","Always check the error from Close(); never discard it in defers","Run filesystem health checks on nodes after any I/O error","Give store data directories dedicated volumes with headroom"],"tags":["store","close","flush","disk"],"backgroundTag":"database-write-failed","analyzedSha":"ee8197d91dd410f6592cb650a94c925ee6dc8bad","analyzedAt":"2026-09-06T09:30:15.973Z","contentChangedAt":"2026-09-06T09:30:15.973Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}