The ticket was marked closed. I ran the actual creation flow on l3 that afternoon and it failed on step one.

Not a subtle failure. After creating a new tournament event, the system redirected to an admin page that no longer existed. A hard 404. Any real user who had gone through that flow would have assumed the event didn’t save and tried again, or called support.

I reopened the ticket. By the end of the day it had produced five commits across five different files in five different layers of the stack.

the redirect was the door, not the bug

The post-save destination after creating a tournament event was a hardcoded page reference. The page it pointed to had been reorganized at some point and nobody had followed the reference forward. One line to fix.

But fixing the redirect uncovered the edit flow.

When you create a new tournament event in the platform and then try to edit it, the admin panel constructs a link back into the event form. That link was being built with a pageId assumption that held for events attached to the original tournament structure. New-style events use a different type identifier. The edit link was generating a URL that either loaded the wrong form or no form at all.

Two broken things from one broken flow. Two different files. Neither fix implied the other.

While I was in the create flow, I noticed that images attached to new events were not surviving the save. The upload succeeded. The preview looked fine. After a page reload, the image was gone.

The image-binding step for tournament events runs through a separate code path from the main form fields. It takes uploaded images and attaches them to the event record by ID. For new events, that step was running before the event record had a stable ID to bind to. The images saved against a temporary identifier and became orphans on reload.

This failure had nothing to do with the redirect or the edit link. It was a sequencing problem inside the create pipeline, invisible unless you uploaded an image and then specifically checked whether it was still there after leaving and returning to the page.

I would not have found it if I had stopped after fixing the redirect.

custom sports exposed an assumption about lists

the platform has a canonical list of sports baked into several places in the admin stack. When you create a tournament event for a recognized sport, the lookup resolves cleanly. When you create one for a custom sport, one that a customer added outside the canonical list, several parts of the flow that look fine on the surface quietly fail.

The sport-handling code in the event create path was doing a lookup against that canonical list and returning a default on miss. Silent substitution. The event would save, but with the wrong sport attached to it.

The form accepted the custom sport. The saved record stored something else. For any customer running tournaments in a sport that was not on the original list, every new event was silently mis-categorized.

The fix was changing the lookup to respect custom sport entries from the database rather than falling back to the canonical default. Four lines. The wrong behavior had been there for a while.

dateText was a string that only looked like a date

Tournament events have a display date field separate from the actual scheduled date. The display field is called dateText and it is freeform. Customers put things like “Saturday, June 7” or “June 7-8” or “TBD.” It is not a parsed date. It is a string.

The form handled this correctly on the way in. The save path was passing it through a date-formatting utility that assumed it was a real date. For any dateText value that did not parse, the utility returned an empty string and overwrote the field.

Customers who entered “June 7-8” would see that value disappear on save. No error message. Just gone, replaced by nothing.

This one lived in the date-handling utility layer, which is shared across multiple parts of the admin. A different file from any of the others.

why l3 and not just local

By the time I had fixes for the redirect, the edit link, the image persistence, the custom sport handling, and the dateText field, I had touched five files across the create pipeline and the admin display layer. Each fix looked correct in isolation. Each had passed a local check.

I had already been wrong once on this ticket. The first hotfix went out the day before, on a diagnosis I was sure of. Cart-created events under an organization parent were inheriting the placeholder value org as their sport, and that broke the photo path and the sub-login. I wrote a driver page that ran three cases against the parent, all three passed on l3, and I shipped it. The next morning a tester hit the same symptoms on a fresh event. The sport value really was wrong, but it was one column of several that the cart’s inline inserts wrote differently from the standard account setup. My driver only checked the column I already believed in, so it could not fail on anything else.

I still ran the full creation flow on l3 with a test payment, because the ticket touched code that runs adjacent to cart registration for paid events. A change in the event create pipeline can produce a checkout flow that looks fine until someone tries to pay for something. The only way to confirm that path is clean is to run it.

The cart path was fine. Finding out on l3 cost five minutes. Finding out from a customer with a failed registration would have cost a day.

That same afternoon, I fixed a stats-page outage that was down across 314 sites. One cause: DataTable hitting an ADO cursor on aggregate queries, producing a result set it could not handle. One fix, one commit. Straightforward in a way that ticket never was. The contrast is useful. One-cause bugs announce themselves clearly. The multi-cause ones look the same from the outside.

what the five failures had in common

The canonical sports list was a reasonable design when the platform launched and the sport list was short. The date formatting step was reasonable when dateText was always a real calendar date. The image-binding step ran after save in the original flow because in the original flow there was no timing problem.

None of these were bugs when they were written. They became bugs when the system around them changed and nobody went back to check every place the old assumption still lived.

A ticket that says “new tournament events are broken” is not telling you there is one broken thing. It is pointing at a feature area that has not been walked end-to-end in a while. The symptom is the entry point. What is behind it is a map of every assumption that was never updated when something adjacent changed.

The only way I found all five was by doing the walk. Not running a targeted test against the specific symptom, but actually going through the flow the same way a user would, watching what happened at each step, and following each new failure forward.

Five files, five layers, one flow that hadn’t been walked in years: the redirect, the edit link, the image binding, the sports lookup, dateText. Each one shipped clean the day it was written and broke quietly the day something next to it changed. That ticket didn’t need a smarter fix. It needed someone to actually create a tournament event, watch the 404, and keep going instead of stopping at line one.