Rubber duck debugging, in writing

The format of a good question turns out to be a debugging step that happens to be readable by other people.

#debugging #culture

There’s a question sitting in a channel right now, half typed, with a stack trace pasted into the middle of it. I’m not going to send it. Somewhere around the part where I had to say what I expected to happen, I stopped and went to look at the thing again. My expectation was the bug.

That happens maybe a third of the time. It used to feel like effort I’d thrown away. It doesn’t anymore.

The list of things you’re supposed to put in a question isn’t etiquette, or at least etiquette isn’t all it is. Every item on it is a place where your own wrong assumption tends to be sitting. So you find out either way: you catch it while typing, or somebody else catches it in four minutes.

The duck can read

This is rubber duck debugging with better ergonomics. The duck works because saying a problem in order forces you to look at each assumption as you go past it. One of them is wrong. Typing it out works for the same reason, and this duck can answer.

It’s also the same shape as debugging by halving. Get the thing to happen on demand, then rule out everything the working case and the broken case have in common. You usually have most of the answer before you’ve formed a hypothesis.

Writing the question does that to your reasoning instead of to your code. Same halving, different input. So the writing is doing work whether or not you send it. That’s worth knowing when you’re sitting there deciding whether to bother anybody.

What are you actually trying to do?

Six things go in. The first one is the one everybody skips.

What you’re trying to achieve, meaning the goal and not the mechanism. Say “I want the section nav to track the page as you scroll” instead of “I’m trying to stop the observer from firing twice.” Every so often somebody replies that you don’t need to do the thing at all. That’s the best possible answer, and you can’t get it if you only describe the approach you already picked.

What you expected. This is where the wrong assumption lives, and a reader can often spot it in a single line. Half the answers I give are some version of “your expectation is the bug.”

What actually happened, verbatim. That means the exact error text, copied instead of paraphrased, and not screenshotted if it’s text. Somebody can search a copied string. Nobody can search a PNG.

What you’ve already ruled out. It saves them from suggesting it (and shows you’ve done some work). If you kept the questions file I keep going on about, you already have it written down.

The smallest reproduction you can manage, not the whole project. Somebody is far more likely to look at 15 lines than at a repository. Shrinking it is usually how you find the bug anyway.

And a specific ask. “Is there a way to tell my own scroll from the user’s?” is answerable. “Any ideas?” is not.

Anybody know much about IntersectionObserver?

That heading is the first of three openings that guarantee silence. I’ve written all three.

The meta-question asks people to volunteer before they know what they’re volunteering for. The only safe move is to keep scrolling, because “yes” might turn out to cost them an hour. Ask the actual question instead. If somebody knows the answer they’ll say so, and if they don’t they’ve lost eight seconds.

The second is “It doesn’t work,” with no reproduction, no error text, and nothing about what you expected. Answering that means conducting an interview, several rounds of it spread over an afternoon. Most people won’t start.

The third is a wall with no question in it. It’s four paragraphs of background and a screenshot of an entire screen, without a question mark anywhere. The reader has to reverse-engineer what you want from them. They’ll probably assume you’re thinking out loud.

None of the three is rude. They’re just expensive. The cost lands on somebody who was in the middle of something else.

Slide into my DMs

The fourth one isn’t about format at all. It’s asking in a direct message.

That halves your odds, because one person is either free or isn’t. It puts the whole cost on that person. And the answer vanishes into a private conversation instead of being findable by the next four people with the same problem.

Am I allowed yet?

People get the math wrong in both directions.

The junior instinct is to keep going for four hours instead of admitting to being stuck, because asking reads as a loss of status. The senior instinct is to say “just ask sooner,” which is fine advice that doesn’t touch the reason anybody was waiting that long.

Asking once you’ve run out of hypotheses has worked for me. Not when it gets hard, and not on a timer. If you’re still coming up with things to try then keep going, because that’s the method working.

When you’re down to changing things at random to see what happens, that’s the moment. For me it usually lands somewhere between 30 minutes and an hour in.

It’s also worth doing the math out loud once. An hour of yours against five minutes of theirs isn’t a close call. It’s the team’s hour either way.

My door is always open

Most of the responsibility here belongs to whoever answers. I say that a lot and don’t always live up to it.

Answer in public. Put it in the channel so it stays findable, instead of in a reply that only goes to one person. More than once I’ve turned up answers to my own questions from three years ago this way, which is a strange feeling.

Answer the question, then say how you’d have found it. “There isn’t a way to tell them apart, and I’d have started with the note in the spec about what counts as a scroll.” The first half unblocks them today. The second half means they don’t need you next time, which is the actual job.

Never reply with “have you read the docs.” If the documentation had a findable answer in it we wouldn’t be here. That reply only tells them the question was beneath you.

The same goes for “just search for it.” If you don’t have time, say you don’t have time.

And give people a number. I’ve said this before and I’ll keep saying it. Telling somebody they should be asking you roughly once an hour for their first two weeks is worth more than any amount of “my door is always open.” It turns permission into an expectation, and an expectation is something a person can meet.

Four minutes

The one I did send, a couple of weeks before the one I didn’t, about an IntersectionObserver doing exactly what I told it to:

The section nav highlights the wrong item for about a second after you click one. My guess is that the smooth scroll drags the page past every section on the way down, the observer treats each one as a real arrival, and the highlight walks down behind you and then settles. Dropping behavior: "smooth" makes it stop, so I think that’s it. I’ve got a flag that ignores the observer until the scroll finishes and it works, but it feels like something I’d be embarrassed to explain in review. Chrome 136, the observer is in section-nav.js around line 40. Is there a way to tell my own scroll from the user’s, or is the flag what everyone does?

The answer came back in four minutes. There’s no way to tell them apart, the flag is what everyone does, and everyone hates it. Somebody else added that scrollend exists now and that I should go and look at the support table, which I did.

section-nav.js
let ignoreObserver = false;
let settle;

link.addEventListener("click", () => {
  ignoreObserver = true;
  clearTimeout(settle);
  settle = setTimeout(() => {
    ignoreObserver = false;
  }, 600);
});
JavaScript

That 600 is a number I picked by feel, and it’s still in there. scrollend would probably do the job properly and I haven’t gone back.

Nobody had anything better than the flag. It was still confirmation that I wasn’t missing something obvious, handed over by somebody who’d already lost an afternoon to it. I think that’s most of what asking gets you. It’s worth a lot, and you only get it if the question can be answered at all.

The other one, still sitting there half typed, got me the same thing for free. I’d like to claim I do that deliberately now. Mostly I still start typing because I want somebody to come rescue me, and the rescue turns out to be the typing. I’ll take it in either order.

Read similar posts

View posts by tag

#accessibility #agency #ai #careers #cross-browser-compatibility #css #culture #debugging #documentation #ecommerce #forms #git #html #images #javascript #performance #php #privacy #scss #security #shopify #small-print #tooling #typography #wordpress