<?xml version="1.0" encoding="utf-8" standalone="no"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0"><channel><title>The Daily WTF</title><link>http://thedailywtf.com/</link><description>Curious Perversions in Information Technology</description><lastBuildDate>Mon, 21 Sep 2026 10:44:13 GMT</lastBuildDate><item><dc:creator>Remy Porter</dc:creator><title>The Weakest Leg</title><link>https://thedailywtf.com/articles/the-weakest-leg</link><category>Feature Articles</category><pubDate>Mon, 21 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/the-weakest-leg</guid><description>&lt;p&gt;On July 10 2026, a life insurance company called TruStage had a &amp;#34;cybersecurity incident&amp;#34;. According to an update posted five days later, when they revealed the incident, they are &amp;#34;continuing to work carefully and urgently to understand the facts, and the company will communicate appropriately as its understanding of the situation evolves.&amp;#34;&lt;/p&gt;
&lt;p&gt;This work, according to their outage page (last updated on September 11th, at the time of this writing), &lt;em&gt;is continuing&lt;/em&gt;. Every major business function is listed as &amp;#34;partially available&amp;#34;. They have some text explaining that they can&amp;#39;t simply turn the system back on, because safety.&lt;/p&gt;
&lt;p&gt;They don&amp;#39;t know what data was compromised. They don&amp;#39;t know when they&amp;#39;ll have everything back up. As of &lt;a href="https://thecudaily.com/more-than-a-dozen-lawsuits-have-now-been-filed-over-trustage-cybersecurity-incident/"&gt;mid-August&lt;/a&gt; they had gotten so far as setting up a &amp;#34;clean&amp;#34; environment that they could start migrating services to. The only good news is that some of their services are supplied to credit unions for banking, &lt;a href="https://hoploninfosec.com/trustage-cybersecurity-incident"&gt;and those were on different systems&lt;/a&gt;, so only their insurance packages were compromised. I also suspect the fact that they serve credit unions is the only thing keeping the business afloat, because failing to handle transactions for &lt;em&gt;months&lt;/em&gt; seems like a terminal event for most businesses.&lt;/p&gt;
&lt;p&gt;Obviously, this also means they&amp;#39;re embroiled in an ever growing number of lawsuits from a variety of parties. It also highlights something about how insurance works: it&amp;#39;s middlemen all the way down.&lt;/p&gt;
&lt;p&gt;TruStage will issue policies, but their connection to the actual policy holder will likely be routed through a number of different partners. Like, for example, Ethos.&lt;/p&gt;
&lt;p&gt;Ethos uses &amp;#34;AI&amp;#34; to &amp;#34;democratize&amp;#34; insurance. Feed your data into their AI, and in minutes they&amp;#39;ll pair you up with a policy. Which, while using machine learning to do things like assess insurance risk seems like a pretty reasonable idea, in this age of AI hype, one has to wonder how this actually is implemented and how it works in practice.&lt;/p&gt;
&lt;p&gt;But Ethos isn&amp;#39;t the end of the chain! Other companies live downstream from Ethos, for example, Family First Life. A customer might reach out to FFL to get a policy, FFL reaches out to Ethos (or one of many other partners), and Ethos reaches out to one of its partners (TruStage being one of their largest), and boom: an insurance happens. Like I said, it&amp;#39;s middlemen all the way down.&lt;/p&gt;
&lt;p&gt;But now, here&amp;#39;s the problem: TruStage issued a bunch of policies, and then stopped being able to do business. They stopped being able to do even vital things, like process payments. And you know what happens when payments aren&amp;#39;t made on a life insurance policy? It lapses. It goes away. You no longer have insurance. And the agents who sell those policies are often paid a commission based on the value of the first few months of the policy&amp;#39;s life (since life insurance is expected to be a long term investment). If the policy lapses, those commissions vanish, companies like Ethos (or downstream partners like FFL) get chargebacks on the value of those failed policies.&lt;/p&gt;
&lt;p&gt;This makes some people, like FFL&amp;#39;s President, Shawn Meaike, &lt;a href="https://hntrbrk.com/breaking-news/ethos-trustage"&gt;very unhappy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What we have here is a pretty egregious failure of cybersecurity and disaster recovery on the part of TruStage. It&amp;#39;s an embarrassing and potentially terminal event for them. It&amp;#39;s awful for the customers who bought insurance policies to give themselves peace of mind, only to discover their policies lapse because TruStage &lt;em&gt;can&amp;#39;t take their money&lt;/em&gt;. It&amp;#39;s creating mild chaos in the entire industry. That&amp;#39;s all interesting, but not why I wanted to write an article about this. I wanted to write about &lt;em&gt;the incredible cringe&lt;/em&gt;.&lt;/p&gt;
&lt;iframe width="920" height="517" src="https://www.youtube.com/embed/hWLKKCXQztg" title="FFL Conference" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""&gt;&lt;/iframe&gt;
&lt;p&gt;In this clip from an insurance industry conference, Meaike brings up all of their partners for a &amp;#34;carrier panel&amp;#34;. He then proceeds to line them up from stage right to stage left, ranking them as &amp;#34;weakest&amp;#34; to &amp;#34;strongest&amp;#34;. Ethos, who sells TruStage policies, is labeled as the weakest.&lt;/p&gt;
&lt;p&gt;&amp;#34;You have the weakest leg,&amp;#34; he says, pointing at the reps from Ethos, to laughter from the audience, and then indicates the other side of the line represents &amp;#34;the strongest leg.&amp;#34; Meaike hands the microphone to an Ethos employee, Dylan Cummings, &amp;#34;We&amp;#39;ll start with you.&amp;#34;&lt;/p&gt;
&lt;p&gt;&amp;#34;I want to start out by thanking everyone,&amp;#34; Cummings says.&lt;/p&gt;
&lt;p&gt;Meaike cuts him off. &amp;#34;Hey, hey, hey, hey. I&amp;#39;m gonna help you. Why don&amp;#39;t you start by saying you&amp;#39;re sorry.&amp;#34;&lt;/p&gt;
&lt;p&gt;The crowd yells out, &amp;#34;Yes!&amp;#34; and applauds this idea.&lt;/p&gt;
&lt;p&gt;&amp;#34;Say &amp;#39;We have a carrier that&amp;#39;s shut down&amp;#39;,&amp;#34; Meakie continues, &amp;#34;&amp;#39;and I&amp;#39;m mother-freaking sorry.&amp;#39;&amp;#34;&lt;/p&gt;
&lt;p&gt;Yes, he said &amp;#34;mother-freaking&amp;#34;, on stage.&lt;/p&gt;
&lt;p&gt;So let&amp;#39;s recap. An insurance company gets pwned so hard they can&amp;#39;t run operations for &lt;em&gt;months&lt;/em&gt;. People&amp;#39;s policies lapse, simply because they can&amp;#39;t &lt;em&gt;give their money&lt;/em&gt; to the insurance company. Which 100% sucks for those customers, though at least with life insurance we expect very few of them are missing their payout- hopefully! This chain cascades through the network of partners, until it culminates in the president of one company publicly humiliating the senior account manager at a middleman company, during an industry conference.&lt;/p&gt;
&lt;p&gt;Nobody comes off looking particularly good here, obviously. Meakie is a jerk. TruStage is institutionally incompetent. Ethos is in a bit of a rock-and-a-hard-place situation, and Cummings is trying to do his best to tap dance his way out of oblivion, but it seems like the AI driven insurance startup just isn&amp;#39;t a good partner even &lt;em&gt;before&lt;/em&gt; their main issuer died.&lt;/p&gt;
&lt;p&gt;All in all, it feels like a Tim Robinson sketch, or perhaps a Nathan Fielder bit. We&amp;#39;re one step away from Meakie calling Cummings a &amp;#34;Wizard of Loneliness.&amp;#34;&lt;/p&gt;
&lt;iframe width="920" height="517" src="https://www.youtube.com/embed/5Ol3pTTVDjU" title="The Wizard of Loneliness (Nathan for You)" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""&gt;&lt;/iframe&gt;
&lt;!-- Easy Reader Version: This isn't viral marketing for Nathan Fielder's new documentary, but it could be if someone wanted to pay me. --&gt;&lt;div&gt;
	[Advertisement] &lt;b&gt;Plan Your .NET 9 Migration with Confidence&lt;/b&gt;&lt;br/&gt;Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. &lt;b&gt;&lt;a href="https://inedo.com/support/whitepapers/dotnet-guide?utm_campaign=dotnet&amp;amp;utm_source=tdwtf-footer"&gt;Download Free Guide Now!&lt;/a&gt;&lt;/b&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;</description><slash:comments>0</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/the-weakest-leg</wfw:comment></item><item><dc:creator>Lyle Seaman</dc:creator><title>Error'd: Ai Dios Mio</title><link>https://thedailywtf.com/articles/ai-dios-mio</link><category>Error'd</category><pubDate>Fri, 18 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/ai-dios-mio</guid><description>&lt;p&gt;It seems like only yesterday we were mocking the AIs for their limits, and tomorrow they&amp;#39;re going to be mocking ours.  In the meantime, here&amp;#39;s a look back at some humorous moments from the last year or so.&lt;/p&gt; &lt;p&gt;&amp;#34;Mathing is hard&amp;#34; wrote
&lt;strong&gt;Timothy W.&lt;/strong&gt;
&amp;#34;I for one welcome our new AI overlords.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#76583f6160c7476d9c13376766f138a0"&gt;&lt;img itemprop="image" border="0" alt="76583f6160c7476d9c13376766f138a0" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/76583f6160c7476d9c13376766f138a0.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;AI is replicating&amp;#34; quipped a clever anon who styled themselves 
&lt;strong&gt;AInonymous&lt;/strong&gt;.
&amp;#34;I don&amp;#39;t want AI features on my phone. And yet,
I&amp;#39;m now getting not just one, but two AI items
on my context menu.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#b4c4dc1e7d4f44958c890478f46db301"&gt;&lt;img itemprop="image" border="0" alt="b4c4dc1e7d4f44958c890478f46db301" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/b4c4dc1e7d4f44958c890478f46db301.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;AI is for the birds&amp;#34; chirped 
&lt;strong&gt;The Beast in Black&lt;/strong&gt;.
&amp;#34;Looks like someone&amp;#39;s AI tool for image classification needs less
of the A and more of the I.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#cebfb8e100d64596bde610304a59b189"&gt;&lt;img itemprop="image" border="0" alt="cebfb8e100d64596bde610304a59b189" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/cebfb8e100d64596bde610304a59b189.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&amp;#34;Get me the ruler&amp;#34; demanded
&lt;strong&gt;Marius B.&lt;/strong&gt;. 
&amp;#34;(note it&amp;#39;s a bit old screenshot) Bing giving great suggestions
for all the bear owners out there.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#ea03bee042b34594a812954e5ef8f395"&gt;&lt;img itemprop="image" border="0" alt="ea03bee042b34594a812954e5ef8f395" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/ea03bee042b34594a812954e5ef8f395.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;AI not so I&amp;#34; spake 
&lt;strong&gt;Olivier&lt;/strong&gt;.
&amp;#34;This translates roughly to &amp;#34;I&amp;#39;m ready to help. Can you
give me the title and description of the article ?&amp;#34;&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#f256bd7b04f9494892d835c623983ff3"&gt;&lt;img itemprop="image" border="0" alt="f256bd7b04f9494892d835c623983ff3" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/f256bd7b04f9494892d835c623983ff3.jpeg"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;

&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	ProGet’s got you covered with security and access controls on your NuGet feeds. &lt;a href="https://inedo.com/proget/private-nuget-server?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=GotYouCoveredFooter&amp;amp;utm_campaign=Cyclops2020"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>14</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/ai-dios-mio</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>CodeSOD: Vintage 2013</title><link>https://thedailywtf.com/articles/vintage-2013</link><category>CodeSOD</category><pubDate>Thu, 17 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/vintage-2013</guid><description>&lt;p&gt;Today we have more of a representative comment, from &lt;strong&gt;Watson&lt;/strong&gt;. This comes from some GPL licensed code published by everybody&amp;#39;s favorite evil empire, Oracle.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;&lt;span class="hljs-comment"&gt;/*
 * Copyright (c) 2011, 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Line breaks added to really show the swamp.&lt;/p&gt;
&lt;p&gt;What was the last year this file was released, I wonder? Clearly some sort of autogeneration gone wrong, but it doesn&amp;#39;t exactly give me a lot of faith in the rest of the code in this file.&lt;/p&gt;
&lt;!-- Easy Reader Version: Thank goodness it's not the 70s or earlier, when a malformed copyright notice could shove a work into the public domain. Fun fact, that's probably why zombie got so popular; Night of the Living Dead slipped into the public domain due to a copyright issue and thus ended up in pretty constant rotation as a late night movie, and got unofficial sequels and the like. See also: It's A Wonderful Life. Which, it's worth noting, Oracle is a million times more evil than Mr Potter, and he'd 100% kill the angel. Actually, that's a riff on the premise I'd love to see, a hardboiled neonoir where even the angelic forces are helpless against greed and violence. Ol' George gets to see a worse world where even heaven holds no sway, and claws his way back to a world where things just *suck*. --&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/buildmaster-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	&lt;a href="https://inedo.com/BuildMaster?utm_source=tdwtf&amp;amp;utm_medium=footerad&amp;amp;utm_term=2018&amp;amp;utm_content=Self_Service&amp;amp;utm_campaign=Buildmaster_Footer"&gt;BuildMaster&lt;/a&gt; allows you to create a self-service release management platform that allows different teams to manage their applications. &lt;a href="https://inedo.com/BuildMaster/download?utm_source=tdwtf&amp;amp;utm_medium=footerad&amp;amp;utm_term=2018&amp;amp;utm_content=Self_Service&amp;amp;utm_campaign=Buildmaster_Footer"&gt;Explore how!&lt;/a&gt; 
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>23</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/vintage-2013</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>CodeSOD: Extremely One Line</title><link>https://thedailywtf.com/articles/extremely-one-line</link><category>CodeSOD</category><pubDate>Wed, 16 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/extremely-one-line</guid><description>&lt;p&gt;Autoformatting your code is a standard thing to do these days. And in those days past, if we&amp;#39;re being honest. There&amp;#39;s no excuse to not use some kind of autoformatter. Whether you configure your editor to do it or are a weirdo like me who runs a formatter from the CLI as a build step, you&amp;#39;ve got an easy way to format your code so it looks neat and readable. And some IDEs, like Visual Studio, are pretty insistent about doing this for you. Which makes today&amp;#39;s code sample a bit more perplexing. This comes from an ancient ASP .Net application that &lt;strong&gt;Austin&lt;/strong&gt; has the misfortune to work with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;&lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;protected&lt;/span&gt; &lt;span class="hljs-keyword"&gt;void&lt;/span&gt; &lt;span class="hljs-title"&gt;Page_PreInit&lt;/span&gt;(&lt;span class="hljs-params"&gt;&lt;span class="hljs-built_in"&gt;object&lt;/span&gt; sender, EventArgs e&lt;/span&gt;)&lt;/span&gt;{&lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (Request.ServerVariables[&lt;span class="hljs-string"&gt;&amp;#34;http_user_agent&amp;#34;&lt;/span&gt;].IndexOf(&lt;span class="hljs-string"&gt;&amp;#34;Safari&amp;#34;&lt;/span&gt;, StringComparison.CurrentCultureIgnoreCase) != &lt;span class="hljs-number"&gt;-1&lt;/span&gt;)Page.ClientTarget = &lt;span class="hljs-string"&gt;&amp;#34;uplevel&amp;#34;&lt;/span&gt;;} &lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;protected&lt;/span&gt; &lt;span class="hljs-keyword"&gt;void&lt;/span&gt; &lt;span class="hljs-title"&gt;Page_Load&lt;/span&gt;(&lt;span class="hljs-params"&gt;&lt;span class="hljs-built_in"&gt;object&lt;/span&gt; sender, EventArgs e&lt;/span&gt;)&lt;/span&gt;
{
 Logic();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which function is &lt;code&gt;Logic()&lt;/code&gt; called from? The fact that I&amp;#39;m asking probably is enough to get you to scroll over. The entire &lt;code&gt;Page_PreInit&lt;/code&gt; function is on a single line, followed by the declaration of the &lt;code&gt;Page_Load&lt;/code&gt; function. A confusing and annoying choice. The real bonus is that if the browser has &amp;#34;Safari&amp;#34; in its user agent, we set a field to a mysterious &amp;#34;uplevel&amp;#34; value. A mix of user agent sniffing, strings as enums/flags, and wonderfully unclear names.&lt;/p&gt;
&lt;p&gt;And yes, this particular pattern appears in more than one page in Austin&amp;#39;s application. Someone thought this was not just a good idea, but good enough to do over and over again.&lt;/p&gt;
&lt;!-- Easy Reader Version: if I could erase user agent strings from the history of web technologies I would, man. --&gt;&lt;div&gt;
	[Advertisement] Picking up &lt;b&gt;NuGet&lt;/b&gt; is easy. Getting good at it takes time. &lt;a href="https://inedo.com/support/whitepapers/nuget-guide?utm_source=tdwtf&amp;amp;utm_medium=Footerad&amp;amp;utm_campaign=nuget"&gt;Download our guide to learn the best practice of NuGet for the Enterprise.&lt;/a&gt;

&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;</description><slash:comments>21</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/extremely-one-line</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>CodeSOD: An Odd Sort</title><link>https://thedailywtf.com/articles/an-odd-sort</link><category>CodeSOD</category><pubDate>Tue, 15 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/an-odd-sort</guid><description>&lt;p&gt;Let&amp;#39;s say we wanted to query Active Directory and print out a report of all of our users, and their last logon time. That seems like a pretty normal task for a Powershell script. It&amp;#39;d probably be short and easy to read, at least if it were written by a normal person.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Alice&lt;/strong&gt; sends us one that wasn&amp;#39;t. She&amp;#39;s already done us a favor, as she writes: &amp;#34;Code cleaned up and indented for the whitespace-missing-impaired.&amp;#34;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-ps1"&gt;&lt;span class="hljs-comment"&gt;#####################################&lt;/span&gt;
&lt;span class="hljs-comment"&gt;# lists accounts and selected attributes alphabetically&lt;/span&gt;
&lt;span class="hljs-comment"&gt;#####################################&lt;/span&gt;

&lt;span class="hljs-keyword"&gt;foreach&lt;/span&gt;( &lt;span class="hljs-variable"&gt;$letter&lt;/span&gt; &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;, &lt;span class="hljs-string"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;, &lt;span class="hljs-string"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;......&lt;span class="hljs-string"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;)
{
     &lt;span class="hljs-variable"&gt;$strfilter&lt;/span&gt; = &lt;span class="hljs-variable"&gt;$letter&lt;/span&gt; + &lt;span class="hljs-string"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;
     &lt;span class="hljs-variable"&gt;$objdomain&lt;/span&gt; = &lt;span class="hljs-built_in"&gt;New-object&lt;/span&gt; System.DirectoryServices.DirectoryEntry
     &lt;span class="hljs-variable"&gt;$objSearcher&lt;/span&gt; = &lt;span class="hljs-built_in"&gt;New-object&lt;/span&gt; System.DirectoryServices.DirectorySearcher
     &lt;span class="hljs-variable"&gt;$objSearcher&lt;/span&gt;.SearchRoot = &lt;span class="hljs-variable"&gt;$objdomain&lt;/span&gt;

     &lt;span class="hljs-variable"&gt;$objSearcher&lt;/span&gt;.Filter = &lt;span class="hljs-variable"&gt;$strFilter&lt;/span&gt;
     &lt;span class="hljs-variable"&gt;$objSearcher&lt;/span&gt;.PropertiesToLoad.Add(&lt;span class="hljs-string"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;);
     &lt;span class="hljs-variable"&gt;$colResults&lt;/span&gt; = &lt;span class="hljs-variable"&gt;$objSearcher&lt;/span&gt;.FindAll()

     &lt;span class="hljs-keyword"&gt;foreach&lt;/span&gt;(&lt;span class="hljs-variable"&gt;$result&lt;/span&gt; &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; &lt;span class="hljs-variable"&gt;$colResults&lt;/span&gt;)
     {
          &lt;span class="hljs-variable"&gt;$name&lt;/span&gt; = &lt;span class="hljs-variable"&gt;$result&lt;/span&gt;.Properties.Name
          &lt;span class="hljs-variable"&gt;$searcher&lt;/span&gt; = &lt;span class="hljs-built_in"&gt;New-Object&lt;/span&gt; DirectoryServices.DirectorySearcher([&lt;span class="hljs-type"&gt;adsi&lt;/span&gt;]&lt;span class="hljs-string"&gt;&amp;#34;&amp;#34;&lt;/span&gt;)
          &lt;span class="hljs-variable"&gt;$searcher&lt;/span&gt;.filter &lt;span class="hljs-string"&gt;&amp;#34;(&amp;amp;(objectCategory=User)(sAMAccountName=&lt;span class="hljs-variable"&gt;$name&lt;/span&gt;))&amp;#34;&lt;/span&gt;
          &lt;span class="hljs-variable"&gt;$users&lt;/span&gt; = searcher.FindAll()
         
          &lt;span class="hljs-keyword"&gt;foreach&lt;/span&gt;(&lt;span class="hljs-variable"&gt;$user&lt;/span&gt; &lt;span class="hljs-keyword"&gt;in&lt;/span&gt; &lt;span class="hljs-variable"&gt;$users&lt;/span&gt;)
          {
               &lt;span class="hljs-built_in"&gt;Write-Output&lt;/span&gt; &lt;span class="hljs-variable"&gt;$user&lt;/span&gt;.properties.item(&lt;span class="hljs-string"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;) + &lt;span class="hljs-string"&gt;&amp;#34;,&amp;#34;&lt;/span&gt; +  &lt;span class="hljs-variable"&gt;$user&lt;/span&gt;.properties.item(&lt;span class="hljs-string"&gt;&amp;#34;lastLogon&amp;#34;&lt;/span&gt;)
          }
     }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This accomplishes sorting alphabetically by iterating across the alphabet. Which, I suspect, isn&amp;#39;t going to actually get them in alphabetical order; it makes sure that &lt;code&gt;albert&lt;/code&gt; and &lt;code&gt;alice&lt;/code&gt; appear before &lt;code&gt;bob&lt;/code&gt;, but doesn&amp;#39;t enforce that &lt;code&gt;albert&lt;/code&gt; must come before &lt;code&gt;alice&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In any case, we iterate across the alphabet, and then create a searcher that finds &lt;code&gt;a*&lt;/code&gt;, then &lt;code&gt;b*&lt;/code&gt;, etc. We explicitly tell the searcher that the only property we care about is the &lt;code&gt;name&lt;/code&gt; field, so that we don&amp;#39;t load unnecessary fields, like the ones we want to report on.&lt;/p&gt;
&lt;p&gt;We then iterate across the list of names, construct a &lt;em&gt;new&lt;/em&gt; searcher, and search for the account with the username we fetched. That lets us get all of the fields we need, including the ones we &lt;em&gt;aren&amp;#39;t&lt;/em&gt; going to use.&lt;/p&gt;
&lt;p&gt;Now, we search for a username, so we expect there to only be one result, but since &lt;code&gt;searcher.FindAll()&lt;/code&gt; returns an array, we &amp;#34;need&amp;#34; to write a loop to iterate across the array of one, which is clearly a better choice than using the &lt;code&gt;FindOne&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;As it usually goes with these sorts of things, one of the managers absolutely adores the fact that they have an easy way to generate a CSV file that they can manipulate in Excel, so this terrible script is &amp;#34;mission critical&amp;#34;.&lt;/p&gt;
&lt;!-- Easy Reader Version: At my current job, I'm on a quest to kill a mission critical spreadsheet which is itself a gigantic nightmare to work with. --&gt;
&lt;style&gt;.comment {border: none;}&lt;/style&gt;&lt;div&gt;
	[Advertisement] Picking up &lt;b&gt;NuGet&lt;/b&gt; is easy. Getting good at it takes time. &lt;a href="https://inedo.com/support/whitepapers/nuget-guide?utm_source=tdwtf&amp;amp;utm_medium=Footerad&amp;amp;utm_campaign=nuget"&gt;Download our guide to learn the best practice of NuGet for the Enterprise.&lt;/a&gt;

&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;</description><slash:comments>13</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/an-odd-sort</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>CodeSOD: I Exist</title><link>https://thedailywtf.com/articles/i-exist</link><category>CodeSOD</category><pubDate>Mon, 14 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/i-exist</guid><description>&lt;p&gt;In addition to using an &lt;a href="https://thedailywtf.com/articles/using-an-ade-ancient-development-environment"&gt;ancient development environment&lt;/a&gt;, with &lt;a href="https://thedailywtf.com/articles/a-more-civilized-age"&gt;terrible UX&lt;/a&gt;, &lt;strong&gt;Greta&lt;/strong&gt; also has the misfortune of working in Pascal.&lt;/p&gt;
&lt;p&gt;Recently, she was diagnosing a bug. The program was reporting that files didn&amp;#39;t exist when they definitely existed. She traced the problem down into the system library. Let&amp;#39;s see if you can spot what&amp;#39;s wrong:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-pascal"&gt;&lt;span class="hljs-comment"&gt;{ Delphi / Kylix Cross-Platform Runtime Library                           }&lt;/span&gt;
&lt;span class="hljs-comment"&gt;{ System Utilities Unit                                                   }&lt;/span&gt;
&lt;span class="hljs-comment"&gt;{                                                                         }&lt;/span&gt;
&lt;span class="hljs-comment"&gt;{ Copyright (c) 1995-2001 Borland Softwrare Corporation                   }&lt;/span&gt;
...

&lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;function&lt;/span&gt; &lt;span class="hljs-title"&gt;FileAge&lt;/span&gt;&lt;span class="hljs-params"&gt;(&lt;span class="hljs-keyword"&gt;const&lt;/span&gt; FileName: &lt;span class="hljs-keyword"&gt;string&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt; Integer;
&lt;span class="hljs-meta"&gt;{$IFDEF MSWINDOWS}&lt;/span&gt;
&lt;span class="hljs-keyword"&gt;var&lt;/span&gt;
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
&lt;span class="hljs-keyword"&gt;begin&lt;/span&gt;
  Handle := FindFirstFile(PChar(FileName), FindData);
  &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; Handle &amp;lt;&amp;gt; INVALID_HANDLE_VALUE &lt;span class="hljs-keyword"&gt;then&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;begin&lt;/span&gt;
    Windows.FindClose(Handle);
    &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (FindData.dwFileAttributes &lt;span class="hljs-keyword"&gt;and&lt;/span&gt; FILE_ATTRIBUTE_DIRECTORY) = &lt;span class="hljs-number"&gt;0&lt;/span&gt; &lt;span class="hljs-keyword"&gt;then&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;begin&lt;/span&gt;
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
        LongRec(Result).Lo) &lt;span class="hljs-keyword"&gt;then&lt;/span&gt; &lt;span class="hljs-keyword"&gt;Exit&lt;/span&gt;;
    &lt;span class="hljs-keyword"&gt;end&lt;/span&gt;;
  &lt;span class="hljs-keyword"&gt;end&lt;/span&gt;;
  Result := -&lt;span class="hljs-number"&gt;1&lt;/span&gt;;
&lt;span class="hljs-keyword"&gt;end&lt;/span&gt;;
&lt;span class="hljs-meta"&gt;{$ENDIF}&lt;/span&gt;

&lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;function&lt;/span&gt; &lt;span class="hljs-title"&gt;FileExists&lt;/span&gt;&lt;span class="hljs-params"&gt;(&lt;span class="hljs-keyword"&gt;const&lt;/span&gt; FileName: &lt;span class="hljs-keyword"&gt;string&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt; Boolean;
&lt;span class="hljs-meta"&gt;{$IFDEF MSWINDOWS}&lt;/span&gt;
&lt;span class="hljs-keyword"&gt;begin&lt;/span&gt;
  Result := FileAge(FileName) &amp;lt;&amp;gt; -&lt;span class="hljs-number"&gt;1&lt;/span&gt;;
&lt;span class="hljs-keyword"&gt;end&lt;/span&gt;;
&lt;span class="hljs-meta"&gt;{$ENDIF}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first function here is &lt;code&gt;FileAge&lt;/code&gt;, which returns the last modified timestamp on a file. Note the use of &lt;code&gt;FileTimeToDosDateTime&lt;/code&gt;, which is a Windows API function. It converts &lt;code&gt;LocalFileTime&lt;/code&gt; and stores the date part in the first output parameter (&lt;code&gt;LongRec(Result).Hi&lt;/code&gt;) and the time part in the second output parameter (&lt;code&gt;LongRec(Result).Lo&lt;/code&gt;). &lt;code&gt;Result&lt;/code&gt;, in this case, is our return value. If anything goes wrong, we return &lt;code&gt;-1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;FileExists&lt;/code&gt; function then, simply calls &lt;code&gt;FileAge&lt;/code&gt;. If it doesn&amp;#39;t return a &lt;code&gt;-1&lt;/code&gt;, there must be a file there.&lt;/p&gt;
&lt;p&gt;That&amp;#39;s an awkward, weird solution to the problem. There has to be a system call that can answer that question more obviously. But it doesn&amp;#39;t seem like it should be blowing up- it looks like it &lt;em&gt;should&lt;/em&gt; work.&lt;/p&gt;
&lt;p&gt;But note that &lt;code&gt;FileTimeToDosDateTime&lt;/code&gt; also returns a boolean value. If it succeeds, great, but if it fails, it returns false and sets an error code you can check. An error code that definitely isn&amp;#39;t being checked.&lt;/p&gt;
&lt;p&gt;And this brings us to the root cause of Greta&amp;#39;s bug: the process that&amp;#39;s writing the files isn&amp;#39;t setting the &amp;#34;last write time&amp;#34;, so while the file exists, the attempt to check its age fails, so &lt;code&gt;FileExists&lt;/code&gt; believes that the file doesn&amp;#39;t exist, just because it doesn&amp;#39;t have a valid timestamp.&lt;/p&gt;
&lt;p&gt;This is the kind of high quality softwrare that sometimes infects our system libraries.&lt;/p&gt;
&lt;!-- Easy Reader Version: Are people going to start putting typos in their code to prove it was human generated? That'd be dumb as hell, which means it's likely to happen. --&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. &lt;a href="https://inedo.com/proget/private-nuget-server?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=PlebsFooter&amp;amp;utm_campaign=Cyclops2020"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>12</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/i-exist</wfw:comment></item><item><dc:creator>Lyle Seaman</dc:creator><title>Error'd: Unrewarding</title><link>https://thedailywtf.com/articles/unrewarding</link><category>Error'd</category><pubDate>Fri, 11 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/unrewarding</guid><description>&lt;p&gt;Some new and some old entries this week, from people who find zero profoundly unrewarding.

&lt;/p&gt;&lt;p&gt;&amp;#34;A scary blue button from The North Face&amp;#34; warns
&lt;strong&gt;Dmitry K.&lt;/strong&gt;.
&amp;#34;Northface has just proudly rewarded me with nothing. I am
not sure whether I want to try adding such a
non-positive amount to my wallet. I am afraid I can
trigger a chain reaction that will crash the financial system
of the whole world...&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#2aecd1f3965e4fb1b5775b07882ea22c"&gt;&lt;img itemprop="image" border="0" alt="2aecd1f3965e4fb1b5775b07882ea22c" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/2aecd1f3965e4fb1b5775b07882ea22c.jpeg"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;0% Steam discount&amp;#34; advises 
&lt;strong&gt;Renan&lt;/strong&gt;
&amp;#34;As much as I love Final Fantasy, I guess I&amp;#39;ll
pass on this 0% discount.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#382f3a11484642a296f81dff7e0c1dc3"&gt;&lt;img itemprop="image" border="0" alt="382f3a11484642a296f81dff7e0c1dc3" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/382f3a11484642a296f81dff7e0c1dc3.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;Give me my money around zero&amp;#34; demands
&lt;strong&gt;Reinier B.&lt;/strong&gt;
&amp;#34;The Nederlandse Spoorwegen (Dutch Railways) owe me €2.25, but apparently
I need to go back in time 2026 years to
get my money (&amp;#34;we&amp;#39;ll transfer the amount to your bank
account around 0&amp;#34;). Or maybe it&amp;#39;s not zero AD but
something else?&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#c4f29dd01c234df3bec4b27c2c0ef39a"&gt;&lt;img itemprop="image" border="0" alt="c4f29dd01c234df3bec4b27c2c0ef39a" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/c4f29dd01c234df3bec4b27c2c0ef39a.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;My relationship with Office Depot is very unrewarding,&amp;#34; complains
&lt;strong&gt;Philip&lt;/strong&gt;.
&amp;#34;Office Depot doesn&amp;#39;t exist in my country anymore (someone signed
up with my email address), but it&amp;#39;s good to know
I have $0 waiting for me if they come back.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#f07379590b0d486c9c952e96416fad45"&gt;&lt;img itemprop="image" border="0" alt="f07379590b0d486c9c952e96416fad45" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/f07379590b0d486c9c952e96416fad45.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;Too late for that!&amp;#34; exclaims an 
&lt;strong&gt;Anonymous&lt;/strong&gt;
&amp;#34;Me hard earned zero award points on this ride app
will expire at the Unix epoch which is apparently coming
up soon.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#f793f3715a6446b9aa5a419ddd2d94ba"&gt;&lt;img itemprop="image" border="0" alt="f793f3715a6446b9aa5a419ddd2d94ba" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/f793f3715a6446b9aa5a419ddd2d94ba.jpeg"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;Rewards point conversion math is hard&amp;#34; figures 
&lt;strong&gt;Emily&lt;/strong&gt;.
&amp;#34;Will I have -0.01 next month? The suspense is killing
me.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#f9c960c680254566b03ba715a93f3f48"&gt;&lt;img itemprop="image" border="0" alt="f9c960c680254566b03ba715a93f3f48" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/09/09/f9c960c680254566b03ba715a93f3f48.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;

&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.&lt;a href="https://inedo.com/proget?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=PlebsFooter"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>7</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/unrewarding</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>A Bit of DNS</title><link>https://thedailywtf.com/articles/a-bit-of-dns</link><category>Feature Articles</category><pubDate>Thu, 10 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/a-bit-of-dns</guid><description>&lt;p&gt;I&amp;#39;m not a DNS person, in that I appreciate that it exists but am not up on the inner workings. It solves a lot of problems with dark magic I don&amp;#39;t fully understand, and fortunately don&amp;#39;t need to.&lt;/p&gt;
&lt;p&gt;But &lt;strong&gt;Lucio&lt;/strong&gt; noticed something that I do think is interesting, within the scope of the CAA record type.&lt;/p&gt;
&lt;p&gt;The CAA record started with &lt;a href="https://datatracker.ietf.org/doc/html/rfc6844"&gt;RFC6844&lt;/a&gt;, which was obsoleted by &lt;a href="https://datatracker.ietf.org/doc/html/rfc8659"&gt;RFC8659&lt;/a&gt;. Both RFCs lay out the same core idea: you can add a CAA record to your DNS entries to say, &amp;#34;hey, this domain over here is allowed to issue certificates for me&amp;#34;. That&amp;#39;s the sort of thing that enables LetsEncrypt to hand out certs, and is an important part of why we can run HTTPS everywhere these days.&lt;/p&gt;
&lt;p&gt;Now, RFC6844 has this in it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Issuer Critical:  If set to &amp;#39;1&amp;#39;, indicates that the corresponding
     property tag MUST be understood if the semantics of the CAA record
     are to be correctly interpreted by an issuer.
		Issuers MUST NOT issue certificates for a domain if the relevant
			CAA Resource Record set contains unknown property tags that have
			the Critical bit set.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The issuer critical flag means that the certificate issuer needs to validate your CAA record before it issues a certificate for you. There&amp;#39;s more in the RFC about what exactly that means, but we don&amp;#39;t care about those details for right now. The rule here is &amp;#34;set a flag to 1&amp;#34;.&lt;/p&gt;
&lt;p&gt;A little later in the RFC, the flag is described in more detail- as a &lt;em&gt;bitmask&lt;/em&gt;. Specifically, bit 0 is the issuer critical flag. Bits 1-7 are reserved for future use.&lt;/p&gt;
&lt;p&gt;Now, here&amp;#39;s where we get into trouble, because programmers don&amp;#39;t understand bits, and because the CAA record expects you to put an integer in this field. So, if you want issuer critical enabled, what value to you put in this field?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;128&lt;/code&gt;, obviously. That&amp;#39;s &lt;code&gt;10000000&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Except, if you don&amp;#39;t understand bits, that&amp;#39;s not obvious. A lot of people read this and decided that the documentation meant they needed to put &lt;code&gt;1&lt;/code&gt; in the field- aka &lt;code&gt;00000001&lt;/code&gt;. This is wrong.&lt;/p&gt;
&lt;p&gt;The updated RFC tries to explain it a bit more clearly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
    Bit 0, Issuer Critical Flag:
        If the value is set to &amp;#34;1&amp;#34;, the Property is critical. A CA MUST NOT issue certificates for any FQDN if the Relevant RRset for that FQDN contains a CAA critical Property for an unknown or unsupported Property Tag. 

Note that according to the conventions set out in [RFC1035], bit 0 is the Most Significant Bit and bit 7 is the Least Significant Bit. Thus, according to those conventions, the Flags value 1 means that bit 7 is set, while a value of 128 means that bit 0 is set.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, pop quiz: what percentage of the people using this field have actually read the RFC? Not many. Probably a number that rounds down to zero, if we&amp;#39;re being honest.&lt;/p&gt;
&lt;p&gt;But now, let&amp;#39;s say you&amp;#39;re LetsEncrypt. You&amp;#39;re supposed to be validating the CAA records of your customers if the bit is set, but a substantial portion of your customers are using it wrong. Do you: stand by the specification and tell them that they&amp;#39;re wrong? Or say, &amp;#34;well, it&amp;#39;s a reserved bit anyway, we&amp;#39;ll (ab)use it and accept bad data&amp;#34;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/letsencrypt/boulder/blob/a0cb60ea6acd264b10fb9ddeeba517b32e503f27/va/caa.go#L220"&gt;Of course they&amp;#39;ll accept bad data&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-go"&gt;&lt;span class="hljs-comment"&gt;// filterCAA processes a set of CAA resource records and picks out the only bits&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// we care about. It returns two slices of CAA records, representing the issue&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// records and the issuewild records respectively, and a boolean indicating&lt;/span&gt;
&lt;span class="hljs-comment"&gt;// whether any unrecognized records had the critical bit set.&lt;/span&gt;
&lt;span class="hljs-function"&gt;&lt;span class="hljs-keyword"&gt;func&lt;/span&gt; &lt;span class="hljs-title"&gt;filterCAA&lt;/span&gt;&lt;span class="hljs-params"&gt;(rrs []*dns.CAA)&lt;/span&gt;&lt;/span&gt; ([]*dns.CAA, []*dns.CAA, &lt;span class="hljs-type"&gt;bool&lt;/span&gt;) {
	&lt;span class="hljs-keyword"&gt;var&lt;/span&gt; issue, issuewild []*dns.CAA
	&lt;span class="hljs-keyword"&gt;var&lt;/span&gt; criticalUnknown &lt;span class="hljs-type"&gt;bool&lt;/span&gt;

	&lt;span class="hljs-keyword"&gt;for&lt;/span&gt; _, caaRecord := &lt;span class="hljs-keyword"&gt;range&lt;/span&gt; rrs {
		&lt;span class="hljs-keyword"&gt;switch&lt;/span&gt; strings.ToLower(caaRecord.Tag) {
		&lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#34;issue&amp;#34;&lt;/span&gt;:
			issue = &lt;span class="hljs-built_in"&gt;append&lt;/span&gt;(issue, caaRecord)
		&lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#34;issuewild&amp;#34;&lt;/span&gt;:
			issuewild = &lt;span class="hljs-built_in"&gt;append&lt;/span&gt;(issuewild, caaRecord)
		&lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#34;iodef&amp;#34;&lt;/span&gt;:
			&lt;span class="hljs-comment"&gt;// We support the iodef property tag insofar as we recognize it, but we&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// never choose to send notifications to the specified addresses. So we&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// do not store the contents of the property tag, but also avoid setting&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// the criticalUnknown bit if there are critical iodef tags.&lt;/span&gt;
			&lt;span class="hljs-keyword"&gt;continue&lt;/span&gt;
		&lt;span class="hljs-keyword"&gt;case&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;#34;issuemail&amp;#34;&lt;/span&gt;, &lt;span class="hljs-string"&gt;&amp;#34;issuevmc&amp;#34;&lt;/span&gt;:
			&lt;span class="hljs-comment"&gt;// We support these property tags insofar as we recognize them and&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// therefore do not bail out if someone has one marked critical. But&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// of course we do not do any further processing, as we do not issue&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// S/MIME or VMC certificates.&lt;/span&gt;
			&lt;span class="hljs-keyword"&gt;continue&lt;/span&gt;
		&lt;span class="hljs-keyword"&gt;default&lt;/span&gt;:
			&lt;span class="hljs-comment"&gt;// The critical flag is the bit with significance 128. However, many CAA&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// record users have misinterpreted the RFC and concluded that the bit&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// with significance 1 is the critical bit. This is sufficiently&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// widespread that that bit must reasonably be considered an alias for&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// the critical bit. The remaining bits are 0/ignore as proscribed by the&lt;/span&gt;
			&lt;span class="hljs-comment"&gt;// RFC.&lt;/span&gt;
			&lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (caaRecord.Flag &amp;amp; (&lt;span class="hljs-number"&gt;128&lt;/span&gt; | &lt;span class="hljs-number"&gt;1&lt;/span&gt;)) != &lt;span class="hljs-number"&gt;0&lt;/span&gt; {
				criticalUnknown = &lt;span class="hljs-literal"&gt;true&lt;/span&gt;
			}
		}
	}

	&lt;span class="hljs-keyword"&gt;return&lt;/span&gt; issue, issuewild, criticalUnknown
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lucio writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now I assume we all agree about the high wisdom of using bitmasks these days. Do we really need to save those bits at the price of a totally screwed up readability?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, I do like bitmasks, because I like the ability to trivially combine a bunch of values together with simple boolean operations, &lt;em&gt;but&lt;/em&gt; I recognize that people can, and &lt;em&gt;do&lt;/em&gt; screw it up. All the time. Am I going to say the DNS people were &lt;em&gt;wrong&lt;/em&gt; for using a bitmask in their networking specification? No, I wouldn&amp;#39;t go that far. But it certainly &lt;em&gt;caused issues&lt;/em&gt;, and I do have to wonder: if you&amp;#39;re treating 7 of 8 bits as reserved, maybe you should just have made it a flag?&lt;/p&gt;
&lt;!-- Easy Reader Version: I do subscribe to the model "if the code was hard to write, it should be hard to read", so bitmasks ahoy! --&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.&lt;a href="https://inedo.com/proget?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=PlebsFooter"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>39</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/a-bit-of-dns</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>CodeSOD: Asynchronous Directories</title><link>https://thedailywtf.com/articles/asynchronous-directories</link><category>CodeSOD</category><pubDate>Wed, 09 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/asynchronous-directories</guid><description>&lt;p&gt;&lt;strong&gt;Eri&lt;/strong&gt; has a mix of a &amp;#34;true confession&amp;#34; and a &amp;#34;wait, really?&amp;#34; today.&lt;/p&gt;
&lt;p&gt;The programming language Vala bills itself as a C# like language that compiles into something pretty close to C performance, designed specifically for writing code against Gnome and its associated libraries.&lt;/p&gt;
&lt;p&gt;One of the C#-isms in brings in is async/await type semantics. You can &lt;code&gt;yield someAsyncFunction()&lt;/code&gt;, which returns control to the caller, allowing it to proceed until the &lt;code&gt;yield&lt;/code&gt;ed function returns an actual value.&lt;/p&gt;
&lt;p&gt;Because it has asynchronous functions, many library functions for handling I/O are already async. So you can &lt;code&gt;make_directory_async&lt;/code&gt;, which yields control so you can keep executing while waiting for the filesystem to make your directory.&lt;/p&gt;
&lt;p&gt;There are also synchronous versions of those methods. And then there&amp;#39;s &lt;code&gt;create_directory_with_parents&lt;/code&gt;, which will create a chain of directories for you. That&amp;#39;s the synchronous version, and Vala&amp;#39;s core library has decided &lt;em&gt;not&lt;/em&gt; to provide an asynchronous version of it, which is my &amp;#34;wait, really?&amp;#34; I suspect it&amp;#39;s really about the race conditions involved and the risks of things going wrong while doing it asynchronously; all solvable problems, but tricky ones to solve.&lt;/p&gt;
&lt;p&gt;But it&amp;#39;s the problem Eri had, and this is their solution:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vala"&gt;&lt;span class="hljs-comment"&gt;/// Note: does not throw if target already exists&lt;/span&gt;
&lt;span class="hljs-keyword"&gt;async&lt;/span&gt; &lt;span class="hljs-keyword"&gt;void&lt;/span&gt; create_directory_with_parents_async(File file, Cancellable? cancellable = &lt;span class="hljs-literal"&gt;null&lt;/span&gt;) throws Error {
	&lt;span class="hljs-keyword"&gt;var&lt;/span&gt; to_create = &lt;span class="hljs-keyword"&gt;new&lt;/span&gt; File[&lt;span class="hljs-number"&gt;0&lt;/span&gt;];
	&lt;span class="hljs-keyword"&gt;var&lt;/span&gt;? current_target = file;
	&lt;span class="hljs-keyword"&gt;while&lt;/span&gt;(current_target != &lt;span class="hljs-literal"&gt;null&lt;/span&gt;) {
		&lt;span class="hljs-keyword"&gt;try&lt;/span&gt; {
			yield current_target.make_directory_async(Priority.DEFAULT, cancellable);
		} &lt;span class="hljs-keyword"&gt;catch&lt;/span&gt;(IOError.NOT_FOUND e) {
			to_create += current_target;
			current_target = current_target.get_parent();
			continue;
		} &lt;span class="hljs-keyword"&gt;catch&lt;/span&gt;(IOError.EXISTS e) {
			&lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
		}
		&lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
	}

	&lt;span class="hljs-keyword"&gt;for&lt;/span&gt; (&lt;span class="hljs-keyword"&gt;int&lt;/span&gt; i = to_create.length - &lt;span class="hljs-number"&gt;1&lt;/span&gt;; i &amp;gt;= &lt;span class="hljs-number"&gt;0&lt;/span&gt;; --i) {
		&lt;span class="hljs-keyword"&gt;try&lt;/span&gt; {
			yield to_create[i].make_directory_async(Priority.DEFAULT, cancellable);
		} &lt;span class="hljs-keyword"&gt;catch&lt;/span&gt;(IOError.EXISTS e) {
			&lt;span class="hljs-comment"&gt;// Created by another process&lt;/span&gt;
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I&amp;#39;m reading this correctly, we start by trying to create the full path to our leaf node. If there&amp;#39;s a not found error, we go up one level and try and create that one. We keep trying that until we either run out of parent nodes to try against, &lt;em&gt;or&lt;/em&gt; we hit a directory that already exists, &lt;em&gt;or&lt;/em&gt; we successfully create a directory. All along the way, we keep appending the &lt;code&gt;current_target&lt;/code&gt; to our &lt;code&gt;to_create&lt;/code&gt; array.&lt;/p&gt;
&lt;p&gt;Once we&amp;#39;ve gotten that baseline, we then iterate across our &lt;code&gt;to_create&lt;/code&gt; array, backwards, creating the shortest non-existent paths first.&lt;/p&gt;
&lt;p&gt;This &lt;em&gt;works&lt;/em&gt;, but it&amp;#39;s ugly as sin. Mostly, it&amp;#39;s ugly because we&amp;#39;re using exceptions for flow control instead of doing things like checking for file existence, though I suppose those checks may also break our goal of doing all our I/O operations in an async context. I don&amp;#39;t know enough about Vala to know the better way of doing this.&lt;/p&gt;
&lt;p&gt;Eri writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The function works as intended, but trying to trace control flow through the first loop is not pleasant. Ironically, the C mechanism Vala wraps is slightly advanced error codes, which would be nicer to work with in this case&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Eri also provides a slightly re-worked version of the main loop, that is at least a bit easier to follow, but still an ugly approach:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-vala"&gt;	&lt;span class="hljs-keyword"&gt;while&lt;/span&gt;(current_target != &lt;span class="hljs-literal"&gt;null&lt;/span&gt;) {
		&lt;span class="hljs-keyword"&gt;try&lt;/span&gt; {
			yield current_target.make_directory_async(Priority.DEFAULT, cancellable);
			&lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
		} &lt;span class="hljs-keyword"&gt;catch&lt;/span&gt;(IOError.EXISTS e) {
			&lt;span class="hljs-keyword"&gt;break&lt;/span&gt;;
		} &lt;span class="hljs-keyword"&gt;catch&lt;/span&gt;(IOError.NOT_FOUND e) {
			to_create += current_target;
			current_target = current_target.get_parent();
		}
	}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Still, since this is an attempt to patch over a missing core library method and solve a tricky problem about how to handle race conditions, I think absolution is reasonable. It&amp;#39;s ugly, it&amp;#39;s weird, but it does the job. Go hide it in a box, and never touch its implementation again- except to make it go away.&lt;/p&gt;
&lt;!-- Easy Reader Version: Is being fully async worth this? --&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. &lt;a href="https://inedo.com/proget/private-nuget-server?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=PlebsFooter&amp;amp;utm_campaign=Cyclops2020"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>15</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/asynchronous-directories</wfw:comment></item><item><dc:creator>Ellis Morning</dc:creator><title>A Mortal Blow</title><link>https://thedailywtf.com/articles/a-mortal-blow</link><category>Feature Articles</category><pubDate>Tue, 08 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/a-mortal-blow</guid><description>&lt;p&gt;From our &lt;b&gt;anonymous&lt;/b&gt; submitter:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Having reached the end of the road at a company increasingly swallowed up companies further east which you&amp;#39;d never believe were still afloat, I found myself headhunted for certain specialty software skills. I was reaching the final few years of my expected working span, so I jumped at the chance. The money was (to me at that time) spectacularly good, so I jumped into it.&lt;/p&gt;
&lt;p style="float:right; padding-left:10px; padding-bottom:10px;"&gt;&lt;a title="Steve Mendel, CC BY 3.0 &amp;lt;https://creativecommons.org/licenses/by/3.0&amp;gt;, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Time_Is_Life,_1080%C3%971920,_154.35_KB.jpg"&gt;&lt;img itemprop="image" width="250" alt="Time Is Life, 1080Ã—1920, 154.35 KB" src="https://thumb.wikimedia.org/wikipedia/commons/thumb/7/72/Time_Is_Life%2C_1080%C3%971920%2C_154.35_KB.jpg/250px-Time_Is_Life%2C_1080%C3%971920%2C_154.35_KB.jpg?utm_source=commons.wikimedia.org&amp;amp;utm_campaign=index&amp;amp;utm_content=thumbnail"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It started when my first day was spent by me being sent home for the weeks it was still going to take to onboard me. Not bad, engaged to wait, as it were, and the first 6 months was thus and so.&lt;/p&gt;
&lt;p&gt;The man who had interviewed me, call him Fred, was intelligent and urbane, and was a joy to meet. He and I clearly hit it off, and lo and behold I was in. It was he who gave me my first assignment, which was mathematical analysis of their core milk-cow program because they needed to find out what it did, and how it did it, so they could perhaps implement it in a more contemporary language.&lt;/p&gt;
&lt;p&gt;So I did that, and was just about to publish my findings with him, when Fred inconveniently dropped dead suddenly. In the what-are-we-going-to-do-now-our-key-man-is-no-more confusion, we contractors were forgotten.&lt;/p&gt;
&lt;p&gt;For the next 18 months or so (may have been more, may have been less) I was more or less ignored. I spent the time writing a development environment to work on any part of the program conveniently, all the while sitting next to a man who was constantly, forcefully and repetitiously speaking ill of the managers in his line structure. The ridiculously garrulous boss who inherited me thought little of me, and handed me the little work that came my way with active hostility. One or two good guys, but mostly a cabal of elderly men trying to preserve their little money-spinner as long as they could, and a johnny-come-lately trying to increase (and even introduce) automatic processes was less than welcome. During that time I spent quite some time on TDWTF, submitting a gem or two here and there.&lt;/p&gt;
&lt;p&gt;No surprise when they finally kicked my arse away. No love lost there. Now working my last couple of years to retirement as a postie.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;No punchline here. I want you to know that &lt;a href="https://news.un.org/en/story/2026/04/1167356"&gt;dropping dead from work&lt;/a&gt; is all too real and can happen to anyone.&lt;/p&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	ProGet’s got you covered with security and access controls on your NuGet feeds. &lt;a href="https://inedo.com/proget/private-nuget-server?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=GotYouCoveredFooter&amp;amp;utm_campaign=Cyclops2020"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>14</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/a-mortal-blow</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>Best of…: Classic WTF: A Dumbain Specific Language</title><link>https://thedailywtf.com/articles/classic-wtf-a-dumbain-specific-language</link><category>Best of…</category><pubDate>Mon, 07 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/classic-wtf-a-dumbain-specific-language</guid><description>&lt;blockquote&gt;It&amp;#39;s a holiday here in the US, a celebration of labor, so we&amp;#39;re reaching back through the archives for a story about an attempt to be labor saving that was not successful. &lt;a href="https://thedailywtf.com/articles/a-dumbain-specific-language"&gt;Original&lt;/a&gt;. --&lt;strong&gt;Remy&lt;/strong&gt;&lt;/blockquote&gt;

&lt;p&gt;I’ve had to write a few domain-specific-languages in the past. As per &lt;a href="https://twitter.com/RemyPorter/status/752913168624746497"&gt;Remy’s Law of Requirements Gathering&lt;/a&gt;, it’s been mostly because the users needed an Excel-like formula language. &lt;!-- Although, more than once, it's been because I wanted to hack a macro system into a DSL for fun, as per my unfinished multiplayer CYOA engine written in Elixir --&gt; The danger of DSLs, of course, is that they’re often YAGNI in the extreme, or at least a sign that you don’t really understand your problem.&lt;/p&gt;

&lt;p&gt;XML, coupled with schemas, is a tool for building data-focused DSLs. If you have some complex structure, you can convert each of its features into an XML attribute. For example, if you had a grammar that looked something like this:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;The Source specification obeys the following syntax

source = ( Feature1+Feature2+... &amp;#34;:&amp;#34; ) ? steps

Feature1 = &amp;#34;local&amp;#34; | &amp;#34;global&amp;#34;

Feature2 =&amp;#34;real&amp;#34; | &amp;#34;virtual&amp;#34; | &amp;#34;ComponentType.all&amp;#34;

Feature3 =&amp;#34;self&amp;#34; | &amp;#34;ancestors&amp;#34; | &amp;#34;descendants&amp;#34; | &amp;#34;Hierarchy.all&amp;#34;

Feature4 = &amp;#34;first&amp;#34; | &amp;#34;last&amp;#34; | &amp;#34;DayAllocation.all&amp;#34;

If features are specified, the order of features as given above has strictly to be followed.

steps = oneOrMoreNameSteps | zeroOrMoreNameSteps | componentSteps

oneOrMoreNameSteps = nameStep ( &amp;#34;.&amp;#34; nameStep ) *

zeroOrMoreNameSteps = ( nameStep &amp;#34;.&amp;#34; ) *

nameStep = &amp;#34;#&amp;#34; name

name is a string of characters from &amp;#34;A&amp;#34;-&amp;#34;Z&amp;#34;, &amp;#34;a&amp;#34;-&amp;#34;z&amp;#34;, &amp;#34;0&amp;#34;-&amp;#34;9&amp;#34;, &amp;#34;-&amp;#34; and &amp;#34;_&amp;#34;. No umlauts allowed, one character is minimum.

componentSteps is a list of valid values, see below.

Valid &amp;#39;componentSteps&amp;#39; are:

- GlobalValue
- Product
- Product.Brand
- Product.Accommodation
- Product.Accommodation.SellingAccom
- Product.Accommodation.SellingAccom.Board
- Product.Accommodation.SellingAccom.Unit
- Product.Accommodation.SellingAccom.Unit.SellingUnit
- Product.OnewayFlight
- Product.OnewayFlight.BookingClass
- Product.ReturnFlight
- Product.ReturnFlight.BookingClass
- Product.ReturnFlight.Inbound
- Product.ReturnFlight.Outbound
- Product.&lt;span onclick="cornify_add();return false;" title="click me!"&gt;Addon&lt;/span&gt;&lt;script type="text/javascript" src="//www.cornify.com/js/cornify.js"&gt;&lt;/script&gt;
- Product.Addon.Service
- Product.Addon.ServiceFeature

In addition to that all subsequent steps from the paths above are permitted, that is &amp;#39;Board&amp;#39;, 
&amp;#39;Accommodation.SellingAccom&amp;#39; or &amp;#39;SellingAccom.Unit.SellingUnit&amp;#39;.
&amp;#39;Accommodation.Unit&amp;#39; in the contrary is not permitted, as here some intermediate steps are missing.&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;You could turn that grammar into an XML document by converting syntax elements to attributes and elements. You could do that, but &lt;strong&gt;Stella’s&lt;/strong&gt; predecessor did not do that. That of course, would have been &lt;em&gt;work&lt;/em&gt;, and they may have had to put some thought on how to relate their homebrew grammar to XSD rules, so instead they created an XML schema rule for &lt;code&gt;SourceAttributeType&lt;/code&gt; that verifies that the data in the field is valid according to the grammar… using regular expressions. 1,310 characters of regular expressions.&lt;/p&gt;
&lt;pre&gt;&lt;code class="xml"&gt;&amp;lt;xs:simpleType&amp;gt;
    &amp;lt;xs:restriction base=&amp;#34;xs:string&amp;#34;&amp;gt;
            &amp;lt;xs:pattern value=&amp;#34;(((Scope.)?(global|local|current)\+?)?((((ComponentType.)?
(real|virtual))|ComponentType.all)\+?)?((((Hierarchy.)?(self|ancestors|descendants))|Hierarchy.all)\+?)?
((((DayAllocation.)?(first|last))|DayAllocation.all)\+?)?:)?(#[A-Za-z0-9\-_]+(\.(#[A-Za-z0-9\-_]+))*|(#[A-Za-z0-
9\-_]+\.)*
(ThisComponent|GlobalValue|Product|Product\.Brand|Product\.Accommodation|Product\.Accommodation\.SellingAccom|Prod
uct\.Accommodation\.SellingAccom\.Board|Product\.Accommodation\.SellingAccom\.Unit|Product\.Accommodation\.Selling
Accom\.Unit\.SellingUnit|Product\.OnewayFlight|Product\.OnewayFlight\.BookingClass|Product\.ReturnFlight|Product\.
ReturnFlight\.BookingClass|Product\.ReturnFlight\.Inbound|Product\.ReturnFlight\.Outbound|Product\.Addon|Product\.
Addon\.Service|Product\.Addon\.ServiceFeature|Brand|Accommodation|Accommodation\.SellingAccom|Accommodation\.Selli
ngAccom\.Board|Accommodation\.SellingAccom\.Unit|Accommodation\.SellingAccom\.Unit\.SellingUnit|OnewayFlight|Onewa
yFlight\.BookingClass|ReturnFlight|ReturnFlight\.BookingClass|ReturnFlight\.Inbound|ReturnFlight\.Outbound|Addon|A
ddon\.Service|Addon\.ServiceFeature|SellingAccom|SellingAccom\.Board|SellingAccom\.Unit|SellingAccom\.Unit\.Sellin
gUnit|BookingClass|Inbound|Outbound|Service|ServiceFeature|Board|Unit|Unit\.SellingUnit|SellingUnit))&amp;#34;/&amp;gt;
    &amp;lt;/xs:restriction&amp;gt;
&amp;lt;/xs:simpleType&amp;gt;
&amp;lt;/xs:union&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There’s a bug in that regex that Stella needed to fix. As she put it: “Every time you evaluate it a few little kitties die because you shouldn’t use kitties to polish your car. I’m so, so sorry, little kitties…”&lt;/p&gt;

&lt;p&gt;The full, unexcerpted code is below, so… at least it has documentation. In two languages!&lt;/p&gt;
&lt;pre&gt;&lt;code class="xml"&gt;&amp;lt;xs:simpleType name=&amp;#34;SourceAttributeType&amp;#34;&amp;gt;
                &amp;lt;xs:annotation&amp;gt;
                        &amp;lt;xs:documentation xml:lang=&amp;#34;de&amp;#34;&amp;gt;
                Die Source Angabe folgt folgender Syntax

                        source = ( Eigenschaft1+Eigenschaft2+... &amp;#34;:&amp;#34; ) ? steps

                        Eigenschaft1 = &amp;#34;local&amp;#34; | &amp;#34;global&amp;#34;

                        Eigenschaft2 =&amp;#34;real&amp;#34; | &amp;#34;virtual&amp;#34; | &amp;#34;ComponentType.all&amp;#34;

                        Eigenschaft3 =&amp;#34;self&amp;#34; | &amp;#34;ancestors&amp;#34; | &amp;#34;descendants&amp;#34; | &amp;#34;Hierarchy.all&amp;#34;

                        Eigenschaft4 = &amp;#34;first&amp;#34; | &amp;#34;last&amp;#34; | &amp;#34;DayAllocation.all&amp;#34;

                        Falls Eigenschaften angegeben werden muss zwingend die oben angegebene Reihenfolge der Eigenschaften eingehalten werden.

                        steps = oneOrMoreNameSteps | zeroOrMoreNameSteps | componentSteps

                        oneOrMoreNameSteps = nameStep ( &amp;#34;.&amp;#34; nameStep ) *

                        zeroOrMoreNameSteps = ( nameStep &amp;#34;.&amp;#34; ) *

                        nameStep = &amp;#34;#&amp;#34; name

                        name ist eine Folge von Zeichen aus der Menge &amp;#34;A&amp;#34;-&amp;#34;Z&amp;#34;, &amp;#34;a&amp;#34;-&amp;#34;z&amp;#34;, &amp;#34;0&amp;#34;-&amp;#34;9&amp;#34;, &amp;#34;-&amp;#34; und &amp;#34;_&amp;#34;. Keine Umlaute. Mindestens ein Zeichen

                        componentSteps ist eine Liste gültiger Werte, siehe im folgenden

                Gültige &amp;#39;componentSteps&amp;#39; sind zunächst:

                        - GlobalValue
                        - Product
                        - Product.Brand
                        - Product.Accommodation
                        - Product.Accommodation.SellingAccom
                        - Product.Accommodation.SellingAccom.Board
                        - Product.Accommodation.SellingAccom.Unit
                        - Product.Accommodation.SellingAccom.Unit.SellingUnit
                        - Product.OnewayFlight
                        - Product.OnewayFlight.BookingClass
                        - Product.ReturnFlight
                        - Product.ReturnFlight.BookingClass
                        - Product.ReturnFlight.Inbound
                        - Product.ReturnFlight.Outbound
                        - Product.Addon
                        - Product.Addon.Service
                        - Product.Addon.ServiceFeature

                Desweiteren sind alle Unterschrittfolgen aus obigen Pfaden erlaubt, also &amp;#39;Board&amp;#39;, &amp;#39;Accommodation.SellingAccom&amp;#39; oder &amp;#39;SellingAccom.Unit.SellingUnit&amp;#39;.
                &amp;#39;Accommodation.Unit&amp;#39; hingegen ist nicht erlaubt, da in diesem Fall einige Zwischenschritte fehlen.

                                &amp;lt;/xs:documentation&amp;gt;
                        &amp;lt;xs:documentation xml:lang=&amp;#34;en&amp;#34;&amp;gt;
                                The Source specification obeys the following syntax

                                source = ( Feature1+Feature2+... &amp;#34;:&amp;#34; ) ? steps

                                Feature1 = &amp;#34;local&amp;#34; | &amp;#34;global&amp;#34;

                                Feature2 =&amp;#34;real&amp;#34; | &amp;#34;virtual&amp;#34; | &amp;#34;ComponentType.all&amp;#34;

                                Feature3 =&amp;#34;self&amp;#34; | &amp;#34;ancestors&amp;#34; | &amp;#34;descendants&amp;#34; | &amp;#34;Hierarchy.all&amp;#34;

                                Feature4 = &amp;#34;first&amp;#34; | &amp;#34;last&amp;#34; | &amp;#34;DayAllocation.all&amp;#34;

                                If features are specified, the order of features as given above has strictly to be followed.

                                steps = oneOrMoreNameSteps | zeroOrMoreNameSteps | componentSteps

                                oneOrMoreNameSteps = nameStep ( &amp;#34;.&amp;#34; nameStep ) *

                                zeroOrMoreNameSteps = ( nameStep &amp;#34;.&amp;#34; ) *

                                nameStep = &amp;#34;#&amp;#34; name

                                name is a string of characters from &amp;#34;A&amp;#34;-&amp;#34;Z&amp;#34;, &amp;#34;a&amp;#34;-&amp;#34;z&amp;#34;, &amp;#34;0&amp;#34;-&amp;#34;9&amp;#34;, &amp;#34;-&amp;#34; and &amp;#34;_&amp;#34;. No umlauts allowed, one character is minimum.

                                componentSteps is a list of valid values, see below.

                                Valid &amp;#39;componentSteps&amp;#39; are:

                                - GlobalValue
                                - Product
                                - Product.Brand
                                - Product.Accommodation
                                - Product.Accommodation.SellingAccom
                                - Product.Accommodation.SellingAccom.Board
                                - Product.Accommodation.SellingAccom.Unit
                                - Product.Accommodation.SellingAccom.Unit.SellingUnit
                                - Product.OnewayFlight
                                - Product.OnewayFlight.BookingClass
                                - Product.ReturnFlight
                                - Product.ReturnFlight.BookingClass
                                - Product.ReturnFlight.Inbound
                                - Product.ReturnFlight.Outbound
                                - Product.Addon
                                - Product.Addon.Service
                                - Product.Addon.ServiceFeature

                                In addition to that all subsequent steps from the paths above are permitted, that is &amp;#39;Board&amp;#39;, &amp;#39;Accommodation.SellingAccom&amp;#39; or &amp;#39;SellingAccom.Unit.SellingUnit&amp;#39;.
                                &amp;#39;Accommodation.Unit&amp;#39; in the contrary is not permitted, as here some intermediate steps are missing.

                        &amp;lt;/xs:documentation&amp;gt;
                &amp;lt;/xs:annotation&amp;gt;
                &amp;lt;xs:union&amp;gt;
                        &amp;lt;xs:simpleType&amp;gt;
                                &amp;lt;xs:restriction base=&amp;#34;xs:string&amp;#34;&amp;gt;
                                        &amp;lt;xs:pattern value=&amp;#34;(((Scope.)?(global|local|current)\+?)?((((ComponentType.)?(real|virtual))|ComponentType.all)\+?)?((((Hierarchy.)?(self|ancestors|descendants))|Hierarchy.all)\+?)?((((DayAllocation.)?(first|last))|DayAllocation.all)\+?)?:)?(#[A-Za-z0-9\-_]+(\.(#[A-Za-z0-9\-_]+))*|(#[A-Za-z0-9\-_]+\.)*(ThisComponent|GlobalValue|Product|Product\.Brand|Product\.Accommodation|Product\.Accommodation\.SellingAccom|Product\.Accommodation\.SellingAccom\.Board|Product\.Accommodation\.SellingAccom\.Unit|Product\.Accommodation\.SellingAccom\.Unit\.SellingUnit|Product\.OnewayFlight|Product\.OnewayFlight\.BookingClass|Product\.ReturnFlight|Product\.ReturnFlight\.BookingClass|Product\.ReturnFlight\.Inbound|Product\.ReturnFlight\.Outbound|Product\.Addon|Product\.Addon\.Service|Product\.Addon\.ServiceFeature|Brand|Accommodation|Accommodation\.SellingAccom|Accommodation\.SellingAccom\.Board|Accommodation\.SellingAccom\.Unit|Accommodation\.SellingAccom\.Unit\.SellingUnit|OnewayFlight|OnewayFlight\.BookingClass|ReturnFlight|ReturnFlight\.BookingClass|ReturnFlight\.Inbound|ReturnFlight\.Outbound|Addon|Addon\.Service|Addon\.ServiceFeature|SellingAccom|SellingAccom\.Board|SellingAccom\.Unit|SellingAccom\.Unit\.SellingUnit|BookingClass|Inbound|Outbound|Service|ServiceFeature|Board|Unit|Unit\.SellingUnit|SellingUnit))&amp;#34;/&amp;gt;
                                &amp;lt;/xs:restriction&amp;gt;
                        &amp;lt;/xs:simpleType&amp;gt;
                &amp;lt;/xs:union&amp;gt;
&amp;lt;/xs:simpleType&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;!-- Easy Reader Version: Something, something, Zalgo joke. --&gt;
&lt;link rel="stylesheet" href="//thedailywtf.com/images/highlight/styles/github.css"/&gt;
&lt;script src="//thedailywtf.com/images/highlight/highlight.pack.js"&gt;&lt;/script&gt;
&lt;script&gt;hljs.initHighlightingOnLoad();&lt;/script&gt;
&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/buildmaster-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	&lt;a href="https://inedo.com/BuildMaster?utm_source=tdwtf&amp;amp;utm_medium=footerad&amp;amp;utm_term=2018&amp;amp;utm_content=Self_Service&amp;amp;utm_campaign=Buildmaster_Footer"&gt;BuildMaster&lt;/a&gt; allows you to create a self-service release management platform that allows different teams to manage their applications. &lt;a href="https://inedo.com/BuildMaster/download?utm_source=tdwtf&amp;amp;utm_medium=footerad&amp;amp;utm_term=2018&amp;amp;utm_content=Self_Service&amp;amp;utm_campaign=Buildmaster_Footer"&gt;Explore how!&lt;/a&gt; 
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>10</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/classic-wtf-a-dumbain-specific-language</wfw:comment></item><item><dc:creator>Lyle Seaman</dc:creator><title>Error'd: Good Time</title><link>https://thedailywtf.com/articles/good-time</link><category>Error'd</category><pubDate>Fri, 04 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/good-time</guid><description>&lt;p&gt;Astute readers noticed last week that this editor (that is to say, me) had his own error&amp;#39;d failure to remember what day it was. Thank you for pointing it out promptly, and then proceeding to send in a bunch of examples of &lt;em&gt;other&lt;/em&gt; sites calendar failures.  Misery loves company!&lt;/p&gt;

&lt;p&gt;Traveler&amp;#39;s travails, from
&lt;strong&gt;C_Chell&lt;/strong&gt; 
&amp;#34;Trying to complete the form on https://www.ihg.com to tell when
I plan to arrive at the hotel, I can&amp;#39;t complete
the form because of this little time problem.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#06036a0253dc4d61b4bd648ab59c2dae"&gt;&lt;img itemprop="image" border="0" alt="06036a0253dc4d61b4bd648ab59c2dae" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/08/30/06036a0253dc4d61b4bd648ab59c2dae.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;You Have -1 Month(s) To Order!&amp;#34; announces 
&lt;strong&gt;dragoncoder047&lt;/strong&gt;.
&amp;#34;Ah, GradImages... the company that told all graduates that they&amp;#39;d
get a free 5x7 but tried to charge me for
it, then refused to honor my &amp;#34;unsubscribe&amp;#34; request and is
*still* emailing me to this day... Can&amp;#39;t do date math?
Par for the course.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#1820ae48b9df4a759ffbde45a8c715e0"&gt;&lt;img itemprop="image" border="0" alt="1820ae48b9df4a759ffbde45a8c715e0" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/08/30/1820ae48b9df4a759ffbde45a8c715e0.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&amp;#34;Stansted Temporal UI design&amp;#34; shared by 
&lt;strong&gt;Michael R.&lt;/strong&gt;
&amp;#34;While waiting for a friend to arrive at Stansted I
see this. I better fire up the DeLorean to pick
her up at 00:06 tomorrow.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#8fa526db89fe46d88d6d2597fe0fa3ae"&gt;&lt;img itemprop="image" border="0" alt="8fa526db89fe46d88d6d2597fe0fa3ae" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/08/30/8fa526db89fe46d88d6d2597fe0fa3ae.jpeg"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;While he was hunting through the website, 
&lt;strong&gt;Michael R.&lt;/strong&gt; also found that
&amp;#34;The Stansted airport website seems to suffer from Directional Confusion.&amp;#34;
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#89c37786ca724e82868eaab4f7285fcf"&gt;&lt;img itemprop="image" border="0" alt="89c37786ca724e82868eaab4f7285fcf" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/08/30/89c37786ca724e82868eaab4f7285fcf.jpeg"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Nothing wrong with the calendar here, but 
&lt;strong&gt;Slaoput&lt;/strong&gt; simply opposes mandatory existence. 
&amp;#34;I was filling out a form that said the Birthdate
is optional, but when I hit submit I found out
it was required. (I guess technically you have to be
born to fill out the form.)&amp;#34;
&lt;br/&gt;&lt;b&gt;NOT&lt;/b&gt; TO BE!
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a href="#8bf00b3dc8ae4ca19481b42b9e63d0f4"&gt;&lt;img itemprop="image" border="0" alt="8bf00b3dc8ae4ca19481b42b9e63d0f4" src="https://d3hvi6t161kfmf.cloudfront.net/images/2026/08/30/8bf00b3dc8ae4ca19481b42b9e63d0f4.jpeg"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/blockquote&gt;
&lt;div&gt;
	[Advertisement] Picking up &lt;b&gt;NuGet&lt;/b&gt; is easy. Getting good at it takes time. &lt;a href="https://inedo.com/support/whitepapers/nuget-guide?utm_source=tdwtf&amp;amp;utm_medium=Footerad&amp;amp;utm_campaign=nuget"&gt;Download our guide to learn the best practice of NuGet for the Enterprise.&lt;/a&gt;

&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;</description><slash:comments>15</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/good-time</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>CodeSOD: Heating Up</title><link>https://thedailywtf.com/articles/heating-up</link><category>CodeSOD</category><pubDate>Thu, 03 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/heating-up</guid><description>&lt;p&gt;A common option for retrofitting heating and cooling into older homes is a mini-split, frequently tied to a heat pump. They&amp;#39;re (relatively) cheap to install, energy efficient, and can be added without substantial modifications to the home. They also, annoyingly, are mostly controlled via IR remotes, making them challenging to wire up to home automation or even a household thermostat.&lt;/p&gt;
&lt;p&gt;People have made solutions, and today&amp;#39;s code comes from one of those solutions. Which, I want to stress, this code comes from an open source project for home automation, so it&amp;#39;s not &lt;em&gt;the code&lt;/em&gt; that&amp;#39;s wrong, here. At first I thought it was, and had a moment of, &amp;#34;I&amp;#39;m not going to pick on some hobby project,&amp;#34; but then I realised the hobby project points at a deeper issue.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;&lt;span class="hljs-comment"&gt;// temperature helper these are direct mappings based on the remote&lt;/span&gt;
&lt;span class="hljs-function"&gt;&lt;span class="hljs-type"&gt;float&lt;/span&gt; &lt;span class="hljs-title"&gt;toFahrenheit&lt;/span&gt;&lt;span class="hljs-params"&gt;(&lt;span class="hljs-type"&gt;float&lt;/span&gt; fromCelsius)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class="hljs-comment"&gt;// Lookup table for specific mappings&lt;/span&gt;
    &lt;span class="hljs-type"&gt;const&lt;/span&gt; std::map&amp;lt;&lt;span class="hljs-type"&gt;float&lt;/span&gt;, &lt;span class="hljs-type"&gt;int&lt;/span&gt;&amp;gt; lookupTable = {
        {&lt;span class="hljs-number"&gt;16.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;61&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;16.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;62&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;17.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;63&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;17.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;64&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;18.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;65&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;18.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;66&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;19.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;67&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;20.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;68&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;21.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;69&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;21.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;70&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;22.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;71&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;22.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;72&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;23.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;73&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;23.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;74&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;24.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;75&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;24.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;76&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;25.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;77&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;25.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;78&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;26.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;79&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;26.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;80&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;27.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;81&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;27.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;82&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;28.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;83&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;28.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;84&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;29.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;85&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;29.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;86&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;30.0&lt;/span&gt;, &lt;span class="hljs-number"&gt;87&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;30.5&lt;/span&gt;, &lt;span class="hljs-number"&gt;88&lt;/span&gt;}
    };

    &lt;span class="hljs-comment"&gt;// Check if the input is in the lookup table&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;auto&lt;/span&gt; it = lookupTable.&lt;span class="hljs-built_in"&gt;find&lt;/span&gt;(fromCelsius);
    &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (it != lookupTable.&lt;span class="hljs-built_in"&gt;end&lt;/span&gt;()) {
        &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; it-&amp;gt;second;
    }

    &lt;span class="hljs-comment"&gt;// Default conversion and rounding to nearest integer&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; &lt;span class="hljs-built_in"&gt;roundf&lt;/span&gt;(fromCelsius * &lt;span class="hljs-number"&gt;1.8&lt;/span&gt; + &lt;span class="hljs-number"&gt;32.0&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay, I &lt;em&gt;am&lt;/em&gt; going to pick on their code a little bit; using &lt;code&gt;float&lt;/code&gt; as a key in a &lt;code&gt;map&lt;/code&gt; is asking for trouble, because rounding errors are going to surprise you. But honestly, failing to find the key you&amp;#39;re looking for is &lt;em&gt;better&lt;/em&gt; than the opposite, since that actually does the correct thing. Because if you look carefully at the table, you&amp;#39;ll see that it&amp;#39;s &lt;em&gt;wrong&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;18C, for example, should be 64F. Well, 64.4F, but we&amp;#39;re rounding to an integer. The choice here is to roughly map every 0.5C increase to a 1F increase, which is not the conversion factor. They try and correct- note how the table mostly steps by 0.5C, but skips 19.5C.&lt;/p&gt;
&lt;p&gt;The opposite direction is similarly bad:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;&lt;span class="hljs-comment"&gt;// temperature helper these are direct mappings based on the remote&lt;/span&gt;
&lt;span class="hljs-function"&gt;&lt;span class="hljs-type"&gt;float&lt;/span&gt; &lt;span class="hljs-title"&gt;toCelsius&lt;/span&gt;&lt;span class="hljs-params"&gt;(&lt;span class="hljs-type"&gt;float&lt;/span&gt; fromFahrenheit)&lt;/span&gt; &lt;/span&gt;{
    &lt;span class="hljs-comment"&gt;// Lookup table for specific mappings&lt;/span&gt;
    &lt;span class="hljs-type"&gt;const&lt;/span&gt; std::map&amp;lt;&lt;span class="hljs-type"&gt;int&lt;/span&gt;, &lt;span class="hljs-type"&gt;float&lt;/span&gt;&amp;gt; lookupTable = {
        {&lt;span class="hljs-number"&gt;61&lt;/span&gt;, &lt;span class="hljs-number"&gt;16.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;62&lt;/span&gt;, &lt;span class="hljs-number"&gt;16.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;63&lt;/span&gt;, &lt;span class="hljs-number"&gt;17.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;64&lt;/span&gt;, &lt;span class="hljs-number"&gt;17.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;65&lt;/span&gt;, &lt;span class="hljs-number"&gt;18.0&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;66&lt;/span&gt;, &lt;span class="hljs-number"&gt;18.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;67&lt;/span&gt;, &lt;span class="hljs-number"&gt;19.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;68&lt;/span&gt;, &lt;span class="hljs-number"&gt;20.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;69&lt;/span&gt;, &lt;span class="hljs-number"&gt;21.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;70&lt;/span&gt;, &lt;span class="hljs-number"&gt;21.5&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;71&lt;/span&gt;, &lt;span class="hljs-number"&gt;22.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;72&lt;/span&gt;, &lt;span class="hljs-number"&gt;22.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;73&lt;/span&gt;, &lt;span class="hljs-number"&gt;23.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;74&lt;/span&gt;, &lt;span class="hljs-number"&gt;23.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;75&lt;/span&gt;, &lt;span class="hljs-number"&gt;24.0&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;76&lt;/span&gt;, &lt;span class="hljs-number"&gt;24.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;77&lt;/span&gt;, &lt;span class="hljs-number"&gt;25.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;78&lt;/span&gt;, &lt;span class="hljs-number"&gt;25.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;79&lt;/span&gt;, &lt;span class="hljs-number"&gt;26.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;80&lt;/span&gt;, &lt;span class="hljs-number"&gt;26.5&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;81&lt;/span&gt;, &lt;span class="hljs-number"&gt;27.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;82&lt;/span&gt;, &lt;span class="hljs-number"&gt;27.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;83&lt;/span&gt;, &lt;span class="hljs-number"&gt;28.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;84&lt;/span&gt;, &lt;span class="hljs-number"&gt;28.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;85&lt;/span&gt;, &lt;span class="hljs-number"&gt;29.0&lt;/span&gt;},
        {&lt;span class="hljs-number"&gt;86&lt;/span&gt;, &lt;span class="hljs-number"&gt;29.5&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;87&lt;/span&gt;, &lt;span class="hljs-number"&gt;30.0&lt;/span&gt;}, {&lt;span class="hljs-number"&gt;88&lt;/span&gt;, &lt;span class="hljs-number"&gt;30.5&lt;/span&gt;}
    };

    &lt;span class="hljs-comment"&gt;// Check if the input is in the lookup table&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;auto&lt;/span&gt; it = lookupTable.&lt;span class="hljs-built_in"&gt;find&lt;/span&gt;(&lt;span class="hljs-built_in"&gt;static_cast&lt;/span&gt;&amp;lt;&lt;span class="hljs-type"&gt;int&lt;/span&gt;&amp;gt;(fromFahrenheit));
    &lt;span class="hljs-keyword"&gt;if&lt;/span&gt; (it != lookupTable.&lt;span class="hljs-built_in"&gt;end&lt;/span&gt;()) {
        &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; it-&amp;gt;second;
    }

    &lt;span class="hljs-comment"&gt;// Default conversion and rounding to nearest 0.5&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; &lt;span class="hljs-built_in"&gt;roundf&lt;/span&gt;((fromFahrenheit - &lt;span class="hljs-number"&gt;32.0&lt;/span&gt;) / &lt;span class="hljs-number"&gt;1.8&lt;/span&gt; * &lt;span class="hljs-number"&gt;2&lt;/span&gt;) / &lt;span class="hljs-number"&gt;2.0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we can be off by as much as a 1C, which is certainly a noticeable feeling.&lt;/p&gt;
&lt;p&gt;At first glance, I thought this was just a misguided attempt at optimizing the lookup. For common values, do a lookup instead of calculating because it&amp;#39;s faster. Seems like the kind of mistake a hobby project might make, and definitely not a WTF. But it&amp;#39;s the comment which corrects me: &lt;code&gt;these are direct mappings based on the remote&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These remotes usually have a display. So when you see on the remote that you&amp;#39;re trying to set the temperature to a comfortable 72F, the remote is actually sending 22.5C to the unit. That&amp;#39;s the actual temperature being sent.&lt;/p&gt;
&lt;p&gt;Now, why on Earth does the remote behave this way? Well, I haven&amp;#39;t cracked one open to read off the part numbers, but I&amp;#39;m going to go out on a limb and guess that the microcontoller in the remote doesn&amp;#39;t handle floating point operations all that well. So it almost certainly does use a lookup table to decide what signal to send, and the lookup table is populated by &amp;#34;good enough&amp;#34; approximations of temperature conversions. There aren&amp;#39;t a &lt;em&gt;lot&lt;/em&gt; of places that use Fahrenheit, so being &amp;#34;close enough&amp;#34; is a reasonable solution. If you want accurate temperatures, use SI units, not &amp;#34;freedom units&amp;#34;.&lt;/p&gt;
&lt;p&gt;In the end, I&amp;#39;d say that neither the hobby project, nor the remote control are the WTF here; locales that insist on using weird ass units are.&lt;/p&gt;
&lt;!-- Easy Reader Version: Rankine is, of course, the most absurd version of this: keep the Fahrenheit scaling, but anchor at absolute zero, like Kelvin, though it's also worth reading up on the both the Newton scale and the Rømer scale, because "coming up with a canonical temperature measurement" was a hard thing to do in the early modern period! It was cutting edge science! Weird scales were a natural reaction to trying to find reproducible conditions. --&gt;
&lt;style&gt;.comment { border: none }&lt;/style&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	ProGet’s got you covered with security and access controls on your NuGet feeds. &lt;a href="https://inedo.com/proget/private-nuget-server?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=GotYouCoveredFooter&amp;amp;utm_campaign=Cyclops2020"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>36</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/heating-up</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>What You Measure</title><link>https://thedailywtf.com/articles/what-you-measure</link><category>Feature Articles</category><pubDate>Wed, 02 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/what-you-measure</guid><description>&lt;p&gt;&lt;strong&gt;Rachel&lt;/strong&gt; joined a new team which was proudly &amp;#34;metrics driven&amp;#34;. When she first met with her boss, Zane, he explained his thinking.&lt;/p&gt;
&lt;p&gt;&amp;#34;We need to be data-driven to make good decisions, right? We&amp;#39;re a manufacturing company. We make widgets. At the end of the day, we need to make the most widgets for the lowest cost of goods sold. So we track that, and that feeds into every decision.&amp;#34;&lt;/p&gt;
&lt;p&gt;The team oversaw an automated production line, which meant the software was a mix of robotics, embedded firmware, high-level web based monitoring tools, and thickets of dreaded PLC code. And because you can&amp;#39;t build an entire factory for test purposes, they only way they could test real-world scales with real-world data was to roll changes out to production. They could simulate, they could run tests on subsets of the system, but a change in the production line software couldn&amp;#39;t truly be validated until it rolled out into the real world.&lt;/p&gt;
&lt;p&gt;Rachel&amp;#39;s first task on the new team involved making some changes to their metrics dashboard. It was viewed as a good way to get her feet wet with the new team. As it turned out, the metrics dashboard was a Google Sheet, with a complex series of formulas that involved multi-level &lt;code&gt;INDEX&lt;/code&gt; functions- essentially querying the spreadsheets like they were a database. Why not use an actual database? Oh, they did — six actually — but the company obeyed Remy&amp;#39;s Law of Requirements Gathering: &amp;#34;no matter what the requirements the users ask for, what they really wanted was Excel&amp;#34;. The database data was pulled into the spreadsheet for reporting.&lt;/p&gt;
&lt;p&gt;Now, a complicated sheet pulling in data from not one, but six different databases, they must have a pretty complex model to explain how changes to their software would impact productivity. And since they needed to model the software to make predictions about how it&amp;#39;d behave in production, that model must be extremely useful.&lt;/p&gt;
&lt;p&gt;Of course it wasn&amp;#39;t. The only metrics they tracked were output metrics, variations on &amp;#34;widgets produced per unit time&amp;#34;. There were some performance metrics, so you could maybe potentially identify &amp;#34;oh, our overall throughput dropped because unit 5 became a bottleneck and started taking 1.5 extra seconds per widget&amp;#34;, but nothing that actually helped you understand how the complex system made decisions. Or even &lt;em&gt;why&lt;/em&gt; unit 5 was taking longer.&lt;/p&gt;
&lt;p&gt;For example, there was an automated quality control scanner. It examined widgets as they came off the line, and rejected defective ones based on a computer vision algorithm. Did that subsystem record why it rejected a widget? No, it did not. The CV model was able to tag widgets with a defect category based on what it saw, but that information didn&amp;#39;t get recorded anywhere. In fact, it didn&amp;#39;t even record how &lt;em&gt;many&lt;/em&gt; widgets got rejected. The only way to know was to have an operator on the assembly line count widgets in the bin manually. Since that ate up a bunch of an operator&amp;#39;s time, it never happened unless the developers begged for it. And since the operator still couldn&amp;#39;t answer the question &amp;#34;why was this widget rejected&amp;#34;, it wasn&amp;#39;t all that useful anyway.&lt;/p&gt;
&lt;p&gt;Every change to the software was scored against the overall output metrics. This meant that when Rachel was ready to push out her first software change, something that would &lt;em&gt;record how many widgets were rejected and why&lt;/em&gt;, whether or not it could be deployed was dependent on seeing the change improve, or at least not regress, the widgets-over-time scores. But the widgets-over-time were a noisy metric; it varied based on which operators were working any given shift, or based on supply chain constraints. Or sometimes, based on when one of the machines was last calibrated- theoretically something that happened on a set schedule, but really was up to the operators. This meant the first three times Rachel rolled her code out for a test run, the metrics regressed. Nothing she changed should have impacted the metrics, but the metrics regressed due to environmental issues.&lt;/p&gt;
&lt;p&gt;This meant making a simple change could take weeks, because you could only do final validation on the real system, which means you had to mark off a block of time for a test run, you could only run a handful of tests a day, and if metrics regressed you had to account for that before you could release the software for actual production use.&lt;/p&gt;
&lt;p&gt;Over the first few months, Rachel added instrumentation to the code. Anything along the way to generating an output widget, she recorded. The hope was that once they had enough data, they could build a useful model of the system. Unfortunately, Zane had other ideas.&lt;/p&gt;
&lt;p&gt;&amp;#34;So, you haven&amp;#39;t improved our metrics,&amp;#34; Zane said. &amp;#34;Which, I remind you, we&amp;#39;re a metrics driven organization. Every change needs to improve our metrics.&amp;#34;&lt;/p&gt;
&lt;p&gt;&amp;#34;Sure, but I&amp;#39;m gathering more data so we have a better idea of what makes our metrics tick. We don&amp;#39;t know why our system does some of the things it does, because we don&amp;#39;t record any logging about the decisions it makes.&amp;#34;&lt;/p&gt;
&lt;p&gt;&amp;#34;Right, but we already gather the key metrics.&amp;#34;&lt;/p&gt;
&lt;p&gt;&amp;#34;But you don&amp;#39;t gather the data that tells you why those metrics are what they are!&amp;#34;&lt;/p&gt;
&lt;p&gt;&amp;#34;Sure,&amp;#34; Zane said. &amp;#34;But those aren&amp;#39;t our key metrics.&amp;#34;&lt;/p&gt;
&lt;p&gt;That, unfortunately for Rachel, was where things landed. Understanding their complex system was a low priority. Pushing top-level metrics without understanding what fed into them, that was the priority. That didn&amp;#39;t mean Rachel was powerless: any time she made a change that she thought might help the top level metrics, she also made sure to add instrumentation that explained how that change behaved. It was the compromise that kept Zane happy: she released features that impacted the top-level metrics, but she also made the system more observable.&lt;/p&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/buildmaster-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	&lt;a href="https://inedo.com/BuildMaster?utm_source=tdwtf&amp;amp;utm_medium=footerad&amp;amp;utm_term=2018&amp;amp;utm_content=Self_Service&amp;amp;utm_campaign=Buildmaster_Footer"&gt;BuildMaster&lt;/a&gt; allows you to create a self-service release management platform that allows different teams to manage their applications. &lt;a href="https://inedo.com/BuildMaster/download?utm_source=tdwtf&amp;amp;utm_medium=footerad&amp;amp;utm_term=2018&amp;amp;utm_content=Self_Service&amp;amp;utm_campaign=Buildmaster_Footer"&gt;Explore how!&lt;/a&gt; 
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>27</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/what-you-measure</wfw:comment></item><item><dc:creator>Remy Porter</dc:creator><title>Representative Line: So Much Room</title><link>https://thedailywtf.com/articles/so-much-room</link><category>Representative Line</category><pubDate>Tue, 01 Sep 2026 06:30:00 GMT</pubDate><guid>https://thedailywtf.com/articles/so-much-room</guid><description>&lt;p&gt;Today&amp;#39;s representative comment ran out of room.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-java"&gt;&lt;span class="hljs-type"&gt;int&lt;/span&gt; &lt;span class="hljs-variable"&gt;maxLen&lt;/span&gt; &lt;span class="hljs-operator"&gt;=&lt;/span&gt; getColumnSize(session, &lt;span class="hljs-string"&gt;&amp;#34;audit&amp;#34;&lt;/span&gt;, &lt;span class="hljs-string"&gt;&amp;#34;text_value1&amp;#34;&lt;/span&gt;) - &lt;span class="hljs-number"&gt;16&lt;/span&gt;; &lt;span class="hljs-comment"&gt;// Leave some room for&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No, it isn&amp;#39;t continued on the next line and just got trimmed out, except perhaps by a careless merge. This is the entire comment.&lt;/p&gt;
&lt;p&gt;Clearly, written by David Chase, the creator of &amp;#34;The Sopranos&amp;#34;.&lt;/p&gt;
&lt;p&gt;There are so many things we might be leaving room for. We could leave some room for dessert. Leave some room for activities. Leave some room for the holy spirit. Leave some room for improvisation.&lt;/p&gt;
&lt;!-- Easy Reader Version: Leave some room for comments --&gt;&lt;div&gt;
	&lt;img src="https://thedailywtf.com/images/inedo/proget-icon.png" style="display:block; float: left; margin: 0 10px 10px 0;"/&gt; [Advertisement] 
	ProGet’s got you covered with security and access controls on your NuGet feeds. &lt;a href="https://inedo.com/proget/private-nuget-server?utm_source=tdwtf&amp;amp;utm_medium=footer&amp;amp;utm_content=GotYouCoveredFooter&amp;amp;utm_campaign=Cyclops2020"&gt;Learn more.&lt;/a&gt;
&lt;/div&gt;
&lt;div style="clear: left;"&gt; &lt;/div&gt;
</description><slash:comments>22</slash:comments><wfw:comment>https://thedailywtf.com/articles/comments/so-much-room</wfw:comment></item></channel></rss>