![]() |
by Lyle Seaman on (#626E1)
England and the United States, according tothe old witticism, are two countries separated by a common language. Thefirst sample deposited in our inbox by Philip B. this week probably demonstrates the aphorism. "I'm all in favor of high-tech solutionsbut what happens if I only want (ahem) a Number One?" he asked. I read, and read again, and couldn't find theslightest thing funny about it. Then I realized that it must be a Brit thing.
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2025-07-01 01:01 |
![]() |
by Remy Porter on (#62534)
The startup life is difficult, at the best of times. It's extra hard when the startup's entire bundle of C-level executives are seniors in college. For the company Aniket Bhattacharyea worked for, they had a product, they had a plan, and they had funding from a Venture Capitalist. More than funding, the VC had their own irons in the fire, and they'd toss subcontracting work to Aniket's startup. It kept the lights on, but it also ate up their capacity to progress the startup's product.One day, the VC had a new product to launch: a children's clothing store. The minimum viable product, in this case, was just a Magento demo with a Vue Storefront front-end. Strict tutorial-mode stuff, which the VC planned to present to stakeholders as an example of what their product could be.Everything was going fine until five minutes before the demo. The VC discovered a show-stopping problem: "The storefront is showing obscene images!"The "obscene" pictures were just photographs of female models, typical for a clothing storefront. But since this was a children's store, the VC was in a panic. "I can't demo this to other investors!"Setting aside the problems of why the VC hadn't noticed this more than five minutes before, Aniket was given his mission: take a pile of replacement images and upload them to the server.Well, with the configuration the server had, there was no way to upload images through the UI. Aniket could SSH in, but that presented a new problem: he didn't have write access to the directory where the files lived.While Aniket tried to make a plan of how to fix this, his phone blew up with texts from both the VC and from the CEO of Aniket's startup. "What's the status?" "What's the ETA?" "You need to go faster."Aniket couldn't overwrite the images, but he did have access to some commands via sudo, specifically managing Nginx. And that gave Aniket an idea.All the images served by the storefront lived under the url /images. Aniket wrote an Nginx rule to redirect /images to port 8000, dropped the new images in a directory that he did have write access to, and then ran python -m http.server 8000 to launch a webserver hosting the files in that directory on port 8000.The VC got to start their demo on time. Aniket closed his laptop and texted his CEO. "I've done the job, but my laptop is now broken. I'm going to take it in for repair." Aniket then went out for a much needed walk and took the rest of the afternoon off. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
|
![]() |
by Remy Porter on (#623S5)
"When inventory drops below the re-order level, we automatically order more," was how the product owner described the requirement to the junior developer. The junior toddled off to work, made their changes. They were not, however, given sufficient supervision, any additional guidance, or any code-reviews.Dan found this in production:
|
![]() |
by Remy Porter on (#622F5)
Microsoft Access represents an "attractive nuisance". It's a powerful database and application development platform designed to enable end users to manage their own data. Empowering users is, in principle, good. But the negative side effect is that you get people who aren't application developers developing applications, which inevitably become business critical.A small company developed an Access Database thirty years ago. It grew, it mutated, it got ported from each Access version to the next. Its tendrils extended outwards, taking over more and more of the business's processes. The ability to maintain and modify the database decayed, updates and bugfixes got slower to make, the whole system got slower. But it limped along roughly at the speed the business required… and then Larry, the user who developed, retired.And that's where Henrietta comes in. She was hired on contract to take this ancient, crufty, Access database and reimplement it in C#, with a WPF front end (because "web application" sounded too scary a shift), with a SQL Server backend. The project was already in-flight, under the sober guidance of internal developers who had analyzed the Access database in detail.There was already a source control server set up- an SVN server. Henrietta found that odd, but odder still was the change history: 100,000 commits from fewer than 20 developers, in only six years. Now, that's not ridiculous- but it's a steady cadence of two commits per developer per day, including weekends and holidays.There was, fortunately, a lot of documentation. None of it was about the code, but instead about the organization. Who works for who, when a given management position was created, how long someone had been in that position. Nothing about the software internals. Definitely nothing about the custom UI framework someone had bolted on top of WPF.When Henrietta noticed she couldn't find documentation about coding standards, or code review processes, she went to one of the other developers and asked: "What's our coding standard? And how do we handle code reviews?""Our whats? I don't know what those are."Well, Henrietta finished up her first ticket, had her commit, and then did what all the other developers did: committed it right into the trunk of the repository.Now, that was her first commit, and it was a training commit: she just needed to add some validation to the UI to make sure it didn't allow empty form fields. With that under her belt, her boss assigned her a new, more complex task. It needed her to make changes in the database, add new workflows to the application, a few screens, and so on."So," she asked, "is there a spec for this somewhere?""Oh," her boss said, "we don't write specs before we develop. Develop the feature and then write specs to describe its behavior."Well, Henrietta didn't like to work that way, so she started by drawing mockups in a diagramming tool. This, as it turned out, was completely new to the organization. No one had ever done a screen mock up before. The handful of diagrams that did exist all were drawn with the same tool: Microsoft Paint.Once Henrietta had decided what her feature was going to look like, she made a feature branch to start her work- and discovered that the way the application was architected, you couldn't conveniently develop in a local branch. In fact, you couldn't even get it to easily point at a development database. Everything had to go through trunk and get pushed to a dev server for testing- one dev server which all the developers had to share.When Henrietta's code didn't work, she found out why: there was a "convenience library" developed by her boss that contained critical functionality for the application. If you didn't call certain methods in that library, the application wouldn't work. These methods were undocumented, and also, no one knew where the code lived. They only used the binary, compiled version of the library.Once Henrietta had reshaped her code around the arcane bondage that the library demanded of her, she had reached the point where she didn't understand her own code anymore. Before she can get into the work of testing the code, a new issue rises to the top of the priority list and she's told to stop what she's doing and tackle that.This was meant to integrate into a 3rd party SOAP-based web service. It transports sensitive data… over HTTP. There's no encryption at all. The WSDL file contains overlapping definitions of two different versions of the API, and the contradictions mean it's possible and easy to send malformed requests with unpredictable behavior. And when it does catch an error, it simply responds with "Error".At this point, months had passed. So it was time for the organization to change their tooling. Everyone was commanded to update to the newest version of .NET Core, a new version of the IDE, and now a new code review tool. Crucible was rolled out with no instructions or guidance, and developers were expected to just start using it.This delayed Henrietta's work on the 3rd party interface, so she went back to the complex feature with database changes. She discovered there are no foreign keys. Also, because there weren't any foreign keys, the data can't have foreign keys added, because the columns that should enforce referential integrity don't match up correctly.Meanwhile, the Project Owner, frustrated by the slow development progress, started writing code themselves. They used the wrong set of project files, pushed it directly to a customer, and caused multiple crashes and downtime for that customer.Back to the database, Henrietta discovered that there's really no abstraction around it, implementation details of the database have to be reimplemented into the UI. She built a UI control that encapsulated at least some of that functionality, and added it to the global UI library. Her boss noticed that change, and told her, "no, that's specific to your module, put it in a local library." Her boss's boss noticed that change, and said, "that UI control is very useful, put it in the global library."Neither boss could agree on the correct location for it, so as a compromise, they created a new "global" library for "accessory controls".Frustrated by all of this, Henrietta decided that she should try and get a local development environment set up. She ended up spending a few days on this, only to discover that certain stored procedures call out to other databases via hard-coded connection strings, and if she tried to run a local copy she'd simply start mangling data in other, production databases. Her boss noticed her spending time on this, and complained that she was wasting her time.When Henrietta finally finished her big feature, she deployed it to the test environment. It blew up, but for reasons she could easily understand, and it only took a few days to fix it. The customer tested the feature, and it wasn't what they thought it was going to be. Once they understood the requirements, which weren't their original requirements, they were happy with the feature, but wished they'd gotten the feature they asked for. With this sign off, the Henrietta pushed the change to production, manually (because why would you automate deployments?). The customer's application immediately crashed because their database was incompatible with the current version of the code. There was, of course, no rollback procedure, so Henrietta was expected to spend a weekend combing through the customer's database to figure out which field contained a value that crashed the application.After that, frustrated, Henrietta went to her boss. "Why are we doing things this way? We're spinning our wheels and making no progress because we have no process, no organization, and everything we do is fragile and we're not doing anything to fix the fundamental problems.""That's the way we do it," her boss said. "Stop asking questions about everything, don't question anything, we're not going to change that. Just do your work or find a new job."Henrietta took that advice to heart, and found a new job. All in all, she spent 8 months fighting her way upstream against a river of crap. It wasn't worth it. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
|
![]() |
by Remy Porter on (#6217H)
In November of 2020, the last IE release happened, and on June 15th of this year, the desktop app officially lost support on Windows 10. But IE never truly dies.Eleanor inherited a web application for a news service. And, you won't be shocked that it's still doing user-agent sniffing to identify the browser. That's just plain bad, but by the standards of user-agent sniffing, it's not terrible code.
|
![]() |
by Lyle Seaman on (#61YBZ)
So much cringe here today. Obviously, the first submission belowjust reeks of professional sycophantry on so many levels. I can'tdecide which is more offensive, the barefoot butcher or the grotesqueattempt to humanize a vogon. To take the edge off, I'll start youout with a very old shaggy dog punchline. The actual setup for thisgroaner is pretty horrible, though someone on the internet has dutifullycompiled the definitive collection of all known variants. Sparingyou that misery, I'll cut straight to the chase: Rudolf the Redknows rain, dear. Now you can decide which gag is more worthy: that, or this.My English vocabulary cannot convey the complexity of my feelings aboutBeatrix W. who shared a monstrosity, reporting innocently"I was just looking for a book about AppleScript by a Japanese author." Is there aJapanese word for "thank you for this gift but never do it again?"
|
![]() |
by Remy Porter on (#61X09)
CSS classes give us the ability to reuse styles in a meaningful way, by defining, well, classes of styling. A common anti-pattern is to misuse classes and define things like "redTextUnderlined" as a CSS class. Best practice is that a CSS class should define the role, not the appearance. So that class might be better named "validationError", for example. A class will frequently bundle together a bunch of stylesheet properties into a single, meaningful name. That's the ideal approach, anyway.Now, Olivia's predecessor had an… interesting philosophy of how to use CSS classes.
|
![]() |
by Remy Porter on (#61VNS)
Annie works in a bioinformatics department. There's a lot of internally developed code, and the quality is… special. But it's also got features that are on their critical path of doing their jobs.One example is that, based on one input form, the next input form needs to display a drop down. The drop down elements don't change, but the individual item that's selected does. So, if the rank HTTP POST variable is set, we want to make sure the matching entry is selected.
|
![]() |
by Remy Porter on (#61TBX)
I started writing a paragraph about why this code Gilda found was bad, and then I had to delete it all, because I wasn't putting the entire block in context. At a glance, this looks almost fine, but I thought I spotted a WTF. But only when I thought about the fact that this C code runs inside of a loop that I realized the real problem.
|
![]() |
by Remy Porter on (#61S2C)
Lets say you have a simple problem. You have a string variable, and you'd like to store that string in another variable. You have a vague understanding of string immutability and something about the way references work in C#, but you don't really understand any of that. So, what do you do?Well, if you're Tina's co-worker, you do this:
|
![]() |
by Lyle Seaman on (#61PEF)
This week we bring you a whole set of submissions that prove,once again, that web programmers just can't keep track of time. But first, a sop with a regular. Is a flying NaN saferthan a Camel? I wouldn't recommend making either a habit.Friend Argle B.is right, submissions to Error'd fromactual desktop applications are rare. He explanes "I routinely expect this from websites. I didNOT expect to find it in MSFS. It came up whenI deleted all the digits." Good for you, Mr. B. Ican't type a lick without digits.
|
![]() |
by Remy Porter on (#61N4K)
Managing datasets is always a challenging task. So when Penny's co-worker needed to collect a pile of latitude/longitude positions from one dataset and prepare it for processing in a C++ program, that co-worker turned to the tools she knew best. Python and C++.Now, you or I might have dumped this data to a CSV file. But this co-worker is more… performance minded than us. So the Python script didn't generate a CSV file. Or a JSON document. Or any standard data file. No, that Python script generated a C++ file.
|
![]() |
by Remy Porter on (#61KQ9)
In mythology, Narcissus was so enraptured by his own beauty that he turned away all potential lovers until he came across a still pool of water. Upon spying his reflection, he fell in love and remained there for the rest of his life. After his death, a narcissus flower grew in his place- a daffodil or jonquil.One important element of Narcissus's myth is that while yes, he was incredibly self-absorbed, he was also beautiful. That's less true for this C# code from frequent commenter Sole Purpose Of Visit. There is nothing beautiful about this code.
|
![]() |
by Remy Porter on (#61JHV)
Sandra (previously) is still working with Bjørn. Bjørn also continues to like keeping things… simple."Simple" for Bjørn is "do as much in PHP as possible since I am okay at PHP, including templating out JavaScript. If I have any third party libraries, just copy and paste them into the project and never, ever use a bundler because WebPack is scary."Which, in Bjørn's defense, WebPack and tools like it are scary, and I hate them all as a class. But that's a separate rant that's wildly off topic, so let's just get back to Bjørn.Because Bjørn does JavaScript via PHP templates, copy/paste, and general "massage the code until it works", we end up with this nonsense line not only getting deployed, but staying deployed until someone has the time and budget to do a large scale refactoring of all of the code:
|
by Ellis Morning on (#61H30)
Lucio worked as a self-employed IT consultant. His clients tended to be small firms with equally small IT departments. When they didn't know where else to turn, they called on Lucio for help.Over the years, Lucio befriended many of the internal IT employees that he worked with. One of them, Fabio, wisely decided to leave his position at a firm with 30 employees, where everyone's roles changed daily depending on the crisis at hand.Soon after, Fabio landed an interview with an 80-person outfit. They were looking for someone who could take care of everything from mouse batteries to Excel spreadsheets to website software updates to issues in their homemade invoicing software.Fabio could handle all of that, except for the software. The last time he'd coded anything was 15 years earlier, and even then he'd decided coding wasn't his forte. The interview was scheduled to take place online; Fabio asked Lucio to be in the room during the interview, hoping for a little secret assistance with any questions that were outside his knowledge.Lucio didn't feel great about it, but he accepted, only to provide help with programming-related stuff and nothing else. As it turned out, the interviewer simply took Fabio's word at face value and did nothing to confirm his coding skills. Lucio never had to intervene, and Fabio got the job all on his own.On the first day of the job, Fabio sent Lucio a selfie of himself at his new workplace. They'd already gotten him a uniform adorned with the company logo. His new boss toured him around the company offices, introducing him to his coworkers.The next day, Fabio contacted Lucio. The company didn't have a helpdesk ticketing system, and Fabio lacked the clout to ask for such a big purchase. Did Lucio know of any free options?As a personal favor, Lucio ended up installing UVDesk Community Edition on one of his own servers and provided Fabio the admin account. He warned his friend that this setup would only be temporary, and he'd have to arrange for something better later.The next day after that, Fabio sought help for the homemade invoicing software, which crashed from time to time. Windows Process Manager was showing a steady increase of allocated memory. Lucio explained to Fabio what a memory leak was, and said that they'd have to look for the problem in the application's source code. Fabio replied that he didn't have access to the code yet.And then, the company website was hacked. Lucio discovered that it was a WordPress site with a handwritten theme. Below is the single.php file responsible for rendering every post:
![]() |
by Lyle Seaman on (#61EKZ)
The submissions this week seemed to have coincidentallydeveloped a theme of self-reference. You tell me.First, persistent Caleb S. tried over and over again to submit this same item for our consideration. He called it a "space-enfolding bus" and said that"There's apparently more space in this Afternoon Tea busthan meets the eye -- you can book seats for 500 adults and 500 children."Alas, his submission came without an image, so we asked for a do-over.Dutifully done, Caleb's second and third attempts both reported "Please use the comments from when I tried to submit this without an image."With that behind us, here is the image from the final attempt.
|
![]() |
by Remy Porter on (#61D8A)
We've all been there. We need to make a change to the codebase or else. The right solution is going to take time and refactoring. There's a quick fix that will keep the production system from falling over and crushing the business. So you make the quick fix, with the idea that, eventually, you'll really fix it.And eventually never comes.But Adam's co-workers have at least found a way to make that process rewarding for the developers involved.This comment was added to the code-base in January, of 2017:
|
![]() |
by Remy Porter on (#61BXP)
Something I see in a lot of code, and generally dislike, is this pattern:
|
![]() |
by Remy Porter on (#61AGF)
One of the common mistakes in a beginner programmer is to wait using a busy loop. Need to pause a program? for(int i = 0; i < SOME_LARGE_NUMBER;i++) continue;There are a lot of good reasons to not do this, but in microcontroller land, sometimes you actually do want to wait this way. There may be better ways, but there also might not- it depends on your specific constraints.So, when David S found these lines of C code, it wasn't precisely a WTF.
|
![]() |
by Remy Porter on (#6196Q)
"The app I work on is a 1.2MLOC big-ball-o-wtf," writes Mark B.As with a lot of big piles of bad code, it's frequently hard to find a snippet that both represents the bad code and is concise enough to submit. In this case, the code in question shows a questionable grasp of both switch statements and enums.
|
![]() |
by Lyle Seaman on (#616TM)
This week we have a veritable grab-bag of all themost common sorts of website errors: the NaN, the null, theundefined, the bad text substitution and the wonky date math.Honestly, they'regetting tedious. Somebody should build a tool to help developers scrub their code of impurities and dross. Theycould call it something catchy like, I dunno, purifieror lintbrush.Timely Todd R. tells us "I left a window open in Workday for too long, and like alot of other apps it threatened to log me out. I justwish I knew when that was..."
|
![]() |
by Lyle Seaman on (#616RP)
This week we have a veritable grab-bag of all themost common sorts of website errors: the NaN, the null, theundefined, the bad text substitution and the wonky date math.Honestly, they'regetting tedious. Somebody should build a tool to help developers scrub their code of impurities and dross. Theycould call it something catchy like, I dunno, purifieror lintbrush.Timely Todd R. tells us "I left a window open in Workday for too long, and like alot of other apps it threatened to log me out. I justwish I knew when that was..."
|
![]() |
by Remy Porter on (#615FC)
Ellen had just finished washing her hands when her phone buzzed. It vibrated itself off the sink, so there was a clumsy moment when it clattered to the restroom floor, and Ellen tried to pick it up with wet hands.After retrieving it and having another round of hand washing, Ellen read the alert: the UPS was in overload.That wasn't good. Their power supply was scaled for future growth- there was more than enough capacity to run all their servers off the UPS. So that meant something was very wrong. Ellen dashed out of the bathroom, conveniently located just off the server room, expecting to see something shorting out and sparking and an ugly cloud of smoke.But everything was fine. Everything in the server room continued to hum along nicely. Barry, the other server room tech, had already checked the UPS management console: something was drawing 2000W above the baseline load. "Something in here must be drawing extra power," Ellen said. Barry agreed, and they went off searching.While they searched, their phones pinged again: the UPS was no longer in overload."Weird," Barry said. "Do you think it's the health monitoring going off?""I mean, it could be," Ellen admitted. "But reporting an overload? I suppose we should open a ticket with the manufacturer."So Ellen did that, while Barry trotted off to make his trip to the restroom. A few hours later, the UPS manufacturer sent their reply, which in short was something like: "You clearly have misconfigured it. Check this wiki article on how to set alert thresholds. Closing this ticket."Frustrated, and full of coffee, Ellen traipsed back to the restroom to relieve herself. This time, she was halfway out the restroom door when her phone buzzed. The UPS was in overload again.Once again, there was nothing obvious going wrong, but the management console reported that something was drawing 2000W above the normal load. "Some device in here has to be going wildly wrong," Ellen said. "Did somebody plug in a fridge, or a space heater or something?""I dunno," Barry said. "Do you think we're going to need to do an inventory?""I suppose so," Ellen said. She checked her phone. "There are a few hours left in the day, let's see if there's some device we don't expect, or something.""Sure, but ah, gotta hit the head first," Barry said. He went to the restroom while Ellen pulled up the inventory of the server room and started walking the racks, looking for anything out of place.That's how they spent the rest of the day, searching through the server room, trying to figure out what might be drawing a whopping 2000W of power off the UPS. There was nothing unusual or out of place, however.Frustrated and annoyed, Ellen took one last trip through the restroom before she left for the day. And, like clockwork, she was just drying her hands on a paper towel when her phone pinged. The UPS was in overload again.Once is chance. Twice is coincidence. Three times is a pattern. When Ellen used the bathroom, the alert went off. When Barry used it, it didn't.Ellen looked around the bathroom. It was a spartan, functional room, without much in it. Lights. Exhaust fan. Sink. Sink. The sink used hot water. On the wall, under the sink, was a petite five liter instant-on hot water heater."Oh, they didn't."The next morning, they got an electrician in. Within a few minutes, Ellen was able to confirm that they, in fact, had: they had wired the bathroom circuit to the server room UPS, not building mains. Every time Ellen washed her hands, the UPS went into overload.The electrician was able to rewire the bathroom, which lifted that additional load off the UPS. That solved the obvious problem, and made everyone happy.Nothing could fix the other problem, however. Ellen couldn't bring herself to shake Barry's hands anymore. Maybe he just used cold water… maybe. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
|
![]() |
by Remy Porter on (#6143Y)
Mario's team had a nasty stutter in the UI of their web application. Frequently, when going back to the server for data, the UI would just hang. The requests themselves were happening asynchronously, and it wasn't just network lag anyway- the server was able to serve up large JSON responses well within any reasonable timelines. Certainly nothing in the timing justified such a nasty UI hang. So what was going on?Well, in many of the places where they were handling JSON responses, specifically large JSON responses, this code was copy-pasted in multiple places:
|
![]() |
by Remy Porter on (#612XH)
I have a bit of a vendetta against the Singleton pattern. It's not to say that I won't use it, it's just that it's a pattern that gets overused and misapplied. The result is, instead of guaranteeing that only one instance of an object exists (because there can be only one), and just reinvent global variables.Today, George sends us some code that is in a Java factory class that constructs thread pools. In this case, the thread pool itself is returned as a singleton. I've got some questions about the logic of why that's the case, but that's what it is.And then there's this method/comment combination which is just… perfect.
|
![]() |
by Alex Papadimoulis on (#611X3)
|
![]() |
by Lyle Seaman on (#60ZAT)
Knock knock.Matthew shared a classic catch-22 that didn't catch any, explaining"Redditstatus.com is in the middle of a Reddit outage (actually,after the outage has been "restored" and we are "monitoring the situation").The whole point of hosting a status page separatelyis so that it does not share common failure mechanism with the site being monitored!"
|
![]() |
by Remy Porter on (#60XXX)
Suri was about to add some new functionality to an existing application, and since it was a relatively big change, she spent a few hours tidying up the codebase. Sitting in there, in the code actually running in production, she found this:
|
![]() |
by Remy Porter on (#60WKQ)
Switches are great. Given a value, you can switch to different code paths based on that value. The problem is… what if you have other conditions too?Well, Hubert's co-worker found a way around that. Here's a heavily anonymized version of the pattern.
|
![]() |
by Remy Porter on (#60V6M)
Kimberly L sends us an example of what is clearly template-generated code, so I think this is an opportunity to go on a rant.Now, the important thing to note here is that this code was in a packaged library that they were considering using.
|
![]() |
by Remy Porter on (#60SXP)
Frequent contributor Argle (previous) is mildly famous, and not just around here. He writes:
|
![]() |
by Lyle Seaman on (#60QAY)
Buffalo, New York is a recovering Rust Belt city which has given theworld several notable achievements. First, a fairly forgettable slicedmeat sandwich au jus more known for its barely edible stale roll thanfor the entirely unremarkable beef entombed within. Second, an innovativerepurposing of a castoff fowl appendage into a drunkard's delicacy (and MlleSimpson's famed befuddlement). Most of all, it's indispensable for the constructionof a lighthearted linguistic shibboleth: Buffalo buffalo buffalo buffalo...and so on. Unfortunately, the city also brings us bad news this week.But first,Tony H. reminds us of a famously scandal-ridden bank. Theirs might not have been the worst fraud in 2016 (or 2017, or 2018,or 2019) but apparently they're now tightening down the screws on consumer lending.Tony observes, frostily, "a credit card with a limit below zero is alarming even for Wells Fargo."
|
![]() |
by Remy Porter on (#60NZ9)
"We have an internal website that shows, among other things, the daily availability of my coworkers for the next three months to help with scheduling, especially when planning vacations," writes Alexander."This vacation planner data is represented as a table. An image of a table to be more precise."Displaying data as images is already a WTF. It's certainly not user friendly, it's definitely not accessible, and it makes one wonder whyyyy. That, however, is the least of the WTFs Alexander has in store for us.First, the front-end sent its HTTP requests to a single end-point. Every request went to the same URL. When the user clicked the button to show the vacation planner, the browser would submit a form- yes a form, creating a body which looked like:
|
![]() |
by Remy Porter on (#60MMH)
Madeline inherited some Python 2.7 code, with an eye towards upgrading it to a more modern Python version. This code generates CSV files, and it's opted to do this by cramming everything into a 2D array in memory and then dumping the array out with some join operations, and that's the real WTF, because that's a guaranteed way to generate invalid CSV files. Like so many things, the CSV files are actually way more complicated than people think.But we're going to focus in on a smaller subset of this pile of WTFs. I'll lead with the caveat from Madeline: "I've changed some of the variable names around, for a bit of anonymity, but couldn't get variable names quite as terrible as the original ones."
|
![]() |
by Remy Porter on (#60K8M)
Christopher Walker continues to struggle against ancient PHP applications in the automotive industry. With the point system behind him, there was a whole pile of internal applications for handling information about laws, misconceptions about the law, and other driver services.One, a home-grown CMS, was useful for publishing blog-style content about changes in the law. There was just one problem: if a post was published without a thumbnail, attempts to view that post failed with an error. It wasn't hard to find the offending line.
|
![]() |
by Remy Porter on (#60J42)
There's an old saying in programming: you don't have to spell correctly, you only have to spell consistently. As long as you mispell everything the same way, your language will understand your code. However, most editors and IDEs have spell-check integration, though, because it's hard to get everyone on a team to spell things wrong consistently.Unless, of course, you know just implement some bonus methods, like John's co-worker. This was frequently spammed in the Java codebase:
|
![]() |
by Remy Porter on (#60FD0)
|
![]() |
by Remy Porter on (#60DZN)
|
![]() |
by Alex Papadimoulis on (#60CM5)
|
![]() |
by Alex Papadimoulis on (#60B8N)
|
![]() |
by Mark Bowytz on (#609YB)
|
![]() |
by Lyle Seaman on (#60713)
I remember when gasoline was under a dollar a gallon inthe US! And penny candy was only a penny! And a poundsterling could buy you a decent dinner, not just a fewounces of meat product! And the euro! Let me tell you about the euro!!
|
![]() |
by Remy Porter on (#605MT)
Crystal Reports falls into that category of tool which promises to help end users accomplish technical tasks easily. They can point it at a database, ask the database a question, and voila, a report pops out, complete with pretty fonts and colors.Like any such tool, however, there's a point where it starts getting technical. Jon's company passed that point ages ago, and hired on a dedicated Crystal Reports Developer to write reports that were too complicated for the end users. But even that has its limits, and eventually, their reporting needs outgrew what a Crystal Report implemented by their dedicated developer could do.So Jon's team was handed a pile of reports and told, "implement these as stored procedures in SqlServer." Now, there wasn't anything so fancy as being given requirements or any sort of description about what the reports were for, or what they did, or what would qualify as a successful port version an error. The reports themselves were the requirements: reverse engineer them exactly as written, doing a 1-to-1 mapping wherever possible.That was mostly fine, but there were a few "special" points in the original reports, where the developer had implemented their own custom Crystal Report functions. Including their own custom date functions. Like this one:
|
![]() |
by Remy Porter on (#6045Y)
Another day, another time where someone from Brian's team needs to log into their MySQL database and kill a query. This particular query hangs while holding a lock, which hangs up every other query which needs to touch this table, which is a lot of them.
|
![]() |
by Remy Porter on (#602SR)
Taffer is the team lead on a team making security products. As such, they have very strict policies about how they write their code, they have very thorough code review systems, and they also have automated tests for everything.And yet, things can still slip through.Taffer submitted this change. It passed two code reviews. It didn't cause any unit tests to fail. It made it into the main branch, and sat there for two months. A team of very experienced, very senior developers didn't catch this glitch until a new hire happened to notice it during a review for something else.
|
![]() |
by Remy Porter on (#601HA)
Annalise has a pile of… unfortunate JavaScript. It's thousands of files with no real organization or logic behind their organization. It's got so much tech debt that it takes a full time developer just to keep it running, let alone provide support or add features or fix bugs. And the backlog of features and bugs is so long that it's best described in terms of א.Which is to say, there's a lot in there that nobody understands. So when you see a bunch of callbacks registered to onFunctionCall, you might assume that this handler is doing… something. You'd be wrong.
|
![]() |
by Lyle Seaman on (#5ZYWV)
Yankee Ezra A.explains the screenshot below at some length. Says he:"I live in Newton, MA, an affluent, wealthy suburb of Boston.In general, city services are excellent, although thehome page of the website is a bit crowded, so I was gladto get an email with a link to the page where I couldsee how the city is handling my request/complaint aboutsidewalks, via the city's 311 service (I have no ideawhat the 311 stands for)When I went to the website, I found what you see in thephoto.I guess one can't really complain about one small errorin a large website." It's certainly an effective strategyfor keeping the complaints box empty!
|
![]() |
by Remy Porter on (#5ZXGT)
Guillaume's company frequently uses consultants. It's a pretty standard setup: Guillaume's employer has many multi-year projects in flight, all of which are layered atop an existing ecosystem of in-house "do everything" applications, each full of their own WTFs.Because of the complexity, Guillaume's team has a pretty strict code review policy. Someone new to the team will write a merge request, a senior developer will coldly review it and provide huge amounts of comments. By the end of the process, the senior team member may have provided most of the code and architecture via those code review comments, and the junior member is left to just follow the instructions.When Guillaume was tasked to review a senior contractor's submission though, that felt like a change of pace. Guillaume still left a lot of comments, but it was more obviously a good merge request. Still, "good" is not "ready for production", and Guillaume ended up in a conflict with management: they wanted the merge now, he wanted the merge right: in compliance with their standards, containing no obvious gotchas, and with clear comments and documentation."This is a senior consultant," Guillaume's boss said, "and they know the product. You need to have a little trust in your senior developers' skills."Guillaume tried to explain that it wasn't about trust; everyone needed their code reviewed because more eyes was better. That didn't budge management, so Guillaume found a compromise: the merge could happen, if there was a follow up to fix the "less urgent comments". That made the users happy, that made Guillaume- well, if not happy, not irritated, and it definitely made the boss happy.One of those "less urgent" comments was on this line:
|
![]() |
by Remy Porter on (#5ZW4H)
Managing true and false values is historically challenging. In the world of C, there's even a history to those challenges. Prior to the C99 standard, there wasn't a standardized version of boolean values, but there was a convention which most applications followed, based on how C conditionals and boolean logic works.In C, anything non-zero is considered "true". So, if(0) { … } won't execute the branch, but if(99) { … } will. As a result, when people wanted to make boolean equivalents, they'd use the C preprocessors to specify something like:
|
![]() |
by Remy Porter on (#5ZTSB)
Matt P was spending a few hours trawling through a Java code base, working through the poorly documented logic and the bugs and the odd conventions. It was the kind of code base that rightly eschewed "magic numbers", favoring constants, but was also the kind of code base which took that to an extreme which arguably didn't help readability.For example:
|