Why triggers pile up in the first place
Apps Script distinguishes between two trigger types: simple triggers (onOpen, onEdit) which are free and stateless, and installable triggers which are registered under your Google account and counted against a quota. Every call to ScriptApp.newTrigger().create() registers a new installable trigger, even if an identical one already exists.
The 20-trigger-per-script limit hits fast when you have a setup() function that you run during development, share with teammates, or call from onOpen to ensure the trigger is present. Each run adds one more entry. The dashboard in Apps Script (Extensions > Triggers) makes this visible, but clearing them by hand across dozens of rows is tedious enough that most people write the code instead.
The first time I hit this, it was a shared Sheet where four people had opened it, each triggering a fresh onOpen that called the installer. That's four time-based triggers for a job meant to run once a day.