The ticket listed three small issues in an event-creation dialog: a file upload that failed on mobile, a name field that cleared on submit, and stale date-placeholder behavior. We started by fixing inputs. The better answer came later, when a design reviewer asked whether this task belonged in a dialog at all.

The production app is an older web application. Modal dialogs were a reasonable choice when it was built, and by the time we worked on this ticket they were load-bearing. The Create Event dialog was one of hundreds of those patterns layered in over the years, each reasonable when it was added, each leaving constraints for the next builder to work around. This one had accumulated fields across multiple event types, and fixing one thing in it reliably broke another.

Input fixes first

That was the wrong turn. We framed the ticket as input-level bugs and worked on it that way, patching the upload, the name field and the placeholders inside the dialog. That framing hid the real problem. The dialog’s state wiring, its width and its surrounding chrome were causing all three symptoms, so each patch ran into the same container.

One question from the design reviewer

During the implementation work, a design reviewer joined and looked at the current modal. One question changed the direction of the day: why is this a dialog at all?

Event creation involved uploads, dates, names, staffing and a mobile-readable flow. Dialogs work well for focused tasks, but this flow had accumulated enough state, recovery needs and responsive layout pressure that the modal no longer supported the task clearly. The special cases were a signal to reconsider the container. They were not proof that every dialog is a mistake.

We routed the create-event task to a dedicated full-page form and retired the dialog path. The page gave the flow room for its inputs, validation, recovery states and responsive layout.

The review made other concrete decisions too. It used language that matched how users described their role, moved the upload action to a clearer place in the task flow, improved the visual hierarchy, and restructured the form around user intent instead of a compact field list. None of that was obvious during implementation, because we were looking at bugs and the reviewer was looking at the task.

What got easier on a page

Once the form was a page, several things that had been hard became straightforward.

The competition-name field had been clearing on submit because of how the dialog’s state was wired. On the page form the value is preserved through the action cycle. Changing the container fixed it, and no patch to the field was needed.

The image upload had a temporary-file lifecycle issue: the handoff location did not survive the expected submission sequence. The page made the states and failure handling easier to inspect, but the fix still needed an explicit, secure upload lifecycle with validation, cleanup and access controls.

Mobile layout had been wrapping inputs into columns that made the form unreadable on anything narrower than 800px. The page wraps correctly because it is no longer constrained by dialog width.

Date placeholders were showing a format string instead of hint text on several browsers. That is a one-line fix once the input is visible and testable in isolation, but in the dialog it had been masked by the surrounding chrome. Input sizing and label alignment got a cleanup pass too. None of it was individually significant, but together they make a form that reads as intentional rather than accumulated.

Where the session artifacts go

One operational side-effect of the day. Screenshots, plans and session artifacts had been landing in ad-hoc locations around the repo, some in tracked directories and some not. By the end of the session we had defined a named constant pointing at a scratch location outside the tracked tree. Future sessions write their temp output there.

It is a small convention. Sessions on an old codebase accumulate a lot of intermediate state, and without a named home for it, that state becomes noise you clean by hand or leave to pollute the repo history.

What the agent did and didn’t do

AI assistance helped implement several bounded fixes once the broken behavior and constraints were clear. It did not broaden this ticket into a product-level container review, because that was not part of the task context. An assistant working on a dialog will usually improve the dialog unless the prompt or the review process explicitly asks whether the container is still appropriate. The design review supplied that missing frame.

An assistant can help compare options when it is given the relevant user evidence and constraints. A product decision with accessibility, workflow and business consequences still needs a collaborator who challenges the frame, validates the experience and decides whether the task surface is still right.

When a form keeps producing small bugs, ask whether the container is the problem before approving more patches. Have someone look at the task flow as well as the code.