One day Heartfelt and Hasty were working on different parts of their company’s product. Heartfelt was fixing an issue where screen-readers couldn’t properly voice the time displayed on a page of their app while Hasty was working on a styling issue. In both cases, unbeknownst to each other, they were fighting a bug where an underlying library was printing the wrong HTML output for the time display.
The bug wasn’t actually too hard to resolve. The library developers made a simple mistake – probably weren’t aware of the proper HTML. When Heartfelt discovered this problem the response was pretty straightforward: clone the underlying library, make and test the simple patch to fix it, then submit a PR to the library. Hasty saw the same problem but didn’t feel empowered like Heartfelt did. Hasty felt powerless.
It turns out that they were both pressing a heavy deadline. Heartfelt knew that a quick workaround was possible, but since Changing Needs would be coming back in a month to update the code Heartfelt didn’t want to make the future work predictably harder. The upstream patch would delay the task at hand by a couple of days but it didn’t block Heartfelt from working on other issues, besides – there was another kind of workaround implemented to fetch the branch from the upstream project until the patch landed in master
.
Hasty felt that getting the todo item crossed off was the best way to show productivity and knew that pushing a fix to the underlying problem required coordination with other people and meant that the task at hand would be finished a couple days later than expected. Hasty thought of a clever workaround: the original HTML output could be parsed and used to recreate the expected output. Hasty added a new function to transform the output, committed the code, and moved on to new tasks.
At the end of the week Heartfelt had no actual changes to the app’s code but the bug was fixed. Not only that, but a large number of websites in the wild were also improved because of the fix. Hasty had a commit then a fix to the commit and the bug was fixed on Thursday, but because the library was fixed by Heartfelt’s changes the part of the app that Hasty had fixed broke again – the assumptions made when transforming the output were now broken. Hasty moved on to another project before someone discovered the new error.
Tired had a reputation of being able to fix things and was pulled in to fix the new bug. Tired had been working with Changing Needs on an important feature update but broken software was a no-no the company wasn’t willing to continue shipping. It took Tired a long time to realize that the transformation code was behind the bug and even longer to understand why it was there in the first place. The commit message said “fixes style” but the change didn’t involve anystyling code and seemed entirely unrelated; entirely unexplained; and entirely confusing. Did Hasty have a specific reason for attempting to transform the output? Why didn’t Hasty directly display the HTML as is the pattern? Eventually Tired realized the addition wasn’t necessary and pulled it out to fix the problem. Changing Needs was upset it took so much time away from the feature update.
We’re not powerless as developers. In most of the software we build we have full control over every layer in the stack. When deadlines are pressing and when we feel overwhelmed I encourage you to think about Heartfelt and Hasty when you decide how to fix bugs and develop features. We constantly make subjective calls: how far down the rabbit hole will I go?
The key differentiator is that Heartfelt was thinking about fellow colleagues and the company as a whole while Hasty was focused on the task at-hand. A quick-bandaid can be much more valuable than a slow fix but there comes a point when compromises…well, compromise the product.
A culture that pushes upstream builds community and shares successes with each other. When something is broken or when something in the system doesn’t meet your needs then you do everyone a favor by reaching out and explaining why that is. It’s even better when you help fix the problem causing the issue. That is, improvements to the framework multiply while workarounds add. Workarounds add code, add maintenance burden, add confusion, and usually add more problems for the future.
If you made it this far then thanks for reading. I hope you are encouraged to be heartfelt when designing your code and when fixing bugs. As organizations grow, communication and consideration become ever more important. We’re trying to do big things and lots of that depends on us promoting a culture of teamwork and contribution while making multiplying changes – sometimes it even means that what makes one team’s or one person’s work slower can actually make the company’s work faster; sometimes it even means that what makes one team’s or one person’s work faster can make the company’s work slower.
Let’s celebrate and promote a culture of pushing upstream!