JuliusBrussee/caveman · error

supersede commit

Error message

supersede commit: %w

What it means

Supersede built the complete lineage change (insert new version, expire old one) but the final tx.Commit() failed, so nothing was persisted. Because it is the last step, this error means the whole supersede was rolled back and the store is unchanged.

Solutions

  1. Free disk space and check filesystem/journal write permissions.
  2. Retry the Supersede — the transaction rolled back, so state is consistent.
  3. Enable busy_timeout so concurrent writers don't block the commit.
  4. Check SQLite journal mode/WAL configuration and device health.

Example fix

// before
mem, err := store.Supersede(oldID, text)
if err != nil { panic(err) }
// after
mem, err := store.Supersede(oldID, text)
if err != nil && strings.Contains(err.Error(), "supersede commit") {
	mem, err = store.Supersede(oldID, text) // safe: tx rolled back
}
Defensive patterns

Strategy: retry

Validate before calling

if free, err := diskFree(storeDir); err != nil || free < minFree { return fmt.Errorf("low disk") }

Try / catch

_, err := store.Supersede(oldID, text)
if err != nil && strings.Contains(err.Error(), "supersede commit") {
	return store.Supersede(oldID, text) // tx rolled back; state consistent
}

Prevention

When it happens

Trigger: Calling Store.Supersede(oldID, newText) when SQLite cannot commit the transaction: disk full at journal time, I/O error, database locked at commit, or process-level interruption.

Common situations: Disk filling up between the INSERT and COMMIT; another connection grabbing a lock that blocks the commit; journal/WAL write permission problems; storage device errors.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/a98902ba9b65677b. Report an issue: GitHub.

Appendix: source

Thrown at mem/store.go:257

		 VALUES (?, ?, ?, ?, ?)`,
		newID, newText, now, now, oldID,
	); err != nil {
		return Memory{}, fmt.Errorf("insert replacement memory: %w", err)
	}
	res, err := tx.Exec(
		`UPDATE memories
		    SET valid_until = ?, superseded_by = ?
		  WHERE id = ? AND valid_until IS NULL`,
		now, newID, oldID,
	)
	if err != nil {
		return Memory{}, fmt.Errorf("expire old memory: %w", err)
	}
	if n, _ := res.RowsAffected(); n != 1 {
		return Memory{}, fmt.Errorf("memory %s changed during supersede", oldID)
	}
	if err := tx.Commit(); err != nil {
		return Memory{}, fmt.Errorf("supersede commit: %w", err)
	}
	return Memory{
		ID:         newID,
		Text:       newText,
		CreatedAt:  now,
		ValidFrom:  now,
		Supersedes: oldID,
	}, nil
}

func validateMemorySize(text string) error {
	if len(text) > MaxMemoryBytes {
		return fmt.Errorf("%w: memory is %d bytes, over the %d-byte cap", ErrMemoryTooLarge, len(text), MaxMemoryBytes)
	}
	return nil
}

// History returns the complete oldest-to-newest supersession chain containing

View on GitHub (pinned to 3ee70a1026)