How to manage unknowns as a web engineer

Working across multiple projects and platforms, web engineers are expected to know a lot of different things.

However, it’s important for us all to stress that we don’t need to know every single technology or concept we’re likely to come across. It’s how you face the unknown that tests your mettle as an engineer, and there are ways to get better at facing unknown problems. I like to think of the problem as an issue of managing unknowns – everything you don’t know is a risk that could cause obstacles or delays, but there are ways to manage that risk consciously and guard against getting stuck.

We work with legacy code touching arcane tools like Backbone.js, various opinionated page builders or meta field management plugins, or browser compatibility shims. We also work with greenfield codebases where we get to push the limits of webpack and React, and work with Altis, Elasticsearch, or what have you. Sometimes we inherit code that is optimised or structured in a way you’ve never seen before. And sometimes a project will face a genuinely new problem or experiment with novel ways of organising code or tackling a common problem, so there’s no simple Googling the answer. The point is: there’s no way any engineer can be expected to know everything going into a project.

One of the most frustrating situations for a developer is to spend time building a piece of functionality, only to find out it wasn’t what the client needed.

I originally started writing this as a post about “tips in asking for help with technical problems”, but as I was writing, I realised that asking for help successfully is part of a bigger mental shift. I’m trying to share some tactics for managing unknowns that have worked for me, in the hopes that they might prove useful to other engineers. I’d love to hear other tips and suggestions that are helpful in addressing work you don’t know anything about going into.

If requirements aren’t clear, clarify them before anything else

One of the most frustrating situations for a developer is to spend time building a piece of functionality, only to find out it wasn’t what the client needed. This happens all the time when a ticket is specified in terms that have a specific technical meaning, but the ticket writer was using them loosely. For example, a ticket might talk about a “block”, which to us means a block editor component, but maybe in this case it was a designer’s shorthand for a bit of markup that could be achieved by a template part, or a shortcode, or a widget, or who knows what else. (The reverse is sometimes true as well – sometimes a specific word in a ticket might be critical to the requirements, but you might assume you understand that they’re really looking for something else).

If a ticket isn’t clear to you, make sure you understand what’s needed before starting work. Writing pseudo-code should help clarify what the steps in a problem are, and this is a first product you can share with the rest of the project team to make sure you’re understanding the problem correctly. And as a bonus, once you have the problem written out in pseudo-code, it should be much easier to see which parts of the problem you already know how to solve, which parts you have a vague idea about, and which parts are still complete unknowns.

Don’t just pad estimates to avoid thinking through a problem

If you’re asked to estimate a task that you don’t have any idea how to tackle, it’s natural to just take what you think is a high estimate, and maybe double it to be safe. This might seem safe, but if the unknowns are left vague at this point, even the most conservative estimate might not be enough. We use consensus estimates (like planning poker) as a way of sharing knowledge about unknowns and validating concerns. Use these tools to your benefit! Communicating what you know and don’t at this step will help you get pointers early on and prevent wasting time chasing down wrong assumptions or unlucky guesses.

You don’t have to have a strict breakdown of how you’ll tackle an issue going into estimations, but you should be able to justify your estimate in some way. For example, “I don’t know how to do this, so I’ll give it a week” isn’t a useful estimate, and you’re just as likely to miss the estimate as you are to hit it if you pick up a ticket with that vague an understanding. But on the other hand, “this ticket involves creating an admin field, outputting that value on the front end, and somehow adding it to a REST endpoint so that I can add a block control” makes it really clear what you know and what you don’t. In that case you could easily say “I know how to do the first two things, but I don’t know exactly how it’s done in this project, so that might take me a day. I don’t know X about the third requirement, so I’ll have to do some research into API permissions. That might add a whole day.”

Isolate the problem you’re stuck on and ask for help there

Sometimes, even after you’ve broken a task down into small chunks and tackled them in a logical order, you’ll still get stuck at a problem that feels too big to track down or explain, and this is the point where it’s hardest to ask for help. It’s a small thing to be able to ask “how can I register a REST field for this post meta field”—as a matter of fact, if your problem is that clear, you can probably answer it yourself with a search. But if you’re stuck at a more vague point in the problem, like “why doesn’t this work?”, it might not be as easy to ask for help where you need it.

The tactic of progressively narrowing down the unknowns is the same when you’re trying to ask for help as it is when you’re trying to debug a problem on your own. Use any of the tools available to you—set debug breakpoints, insert var dumps, write unit tests—to pinpoint just where the expected behaviour is breaking down. This might be enough to find the problem! And if not, you should at least have enough context to ask a clearly defined question. Work with the people trying to help you.

Finally, make sure you’re giving people enough information to answer your question. It’s often tough to guess from a description of a problem what’s actually going on – if you can share links to your code or a gist, that helps. If an approach doesn’t work for you, explain what the problem or concern is with it – just saying “I tried that, didn’t work” to any suggestions people offer is a sure way to frustrate them and yourself.

Documenting the solutions you find after getting help is also a great way to foster an environment where supporting each other is encouraged. Answering questions on Slack, pair programming, and support take time, and feels much better to the person putting in that time if the knowledge you arrive at is shared publicly at the end of it. Any bug that one person faces and figures out should contribute to the overall knowledge pool accessible by the rest of the team.

Practice brings comfort

Learning how to manage unknowns is a skill developed over time. In a recent conversation we had internally, the team talked about how a principal engineer is expected to be able to “fight fires” by coming into any project and figuring out what needs to be done to get it finished, no matter what technology or tools it involves. This may or may not be a reasonable expectation, but my point is that the ability to work around what you don’t know is something that can be learned; starting with managing unknowns at the feature level until you’re comfortable looking at a codebase where everything is new to you.

Part of this is just developing instincts and learning to trust your gut. It may never feel comfortable to estimate a task you have no idea how to do. I know from the times when I did sales engineering work that I’ll always feel a moment of panic after committing myself to a huge abstraction like “we can do this project in 130 developer days”. I get the same feeling when I start on a ticket and have to spend a couple of hours investigating an approach before I know if it’ll even be possible or not.

But over time, through paying attention to the shape of what you know and don’t know, you can get to a point where your estimates are close most of the time, your instincts of where to look for a bug are usually good, and you can often give enough context to get a decent answer to your questions.