When a required configuration value is missing at the start of an automated run, should the run fail immediately or fall back to a built-in default?
answer
- Loud and early beats quiet and wrong
- Declare each key required or defaulted
- Validate the whole set before case one
- Report every missing key, not the first
basics
~20 sFail immediately, before the first case, naming the missing key and the layers searched. A silent default turns a configuration mistake into either a green run against the wrong thing or a wave of failures that blame the product.
solid answer
~50 sDeclare each key as **required** or **optional with a declared default**, then validate the whole resolved set once, after resolution and before the first case. A required key with no value should abort with a message naming the key, its expected shape, and every layer that was searched: one loud failure a person fixes in seconds. Silent fallback produces the two worse outcomes instead — a suite that passes because it quietly checked almost nothing, or a scatter of case failures whose messages accuse the product of behaviour it never exhibited. Optional keys are those where one value is right nearly everywhere and being wrong costs only time, such as worker count or artefact location; even those belong in the echoed effective configuration so nobody has to guess which default applied. Validate everything in one pass so a run reports all missing keys, not the first.
code
pseudocode · 12 linesproblems = []
for key, spec in declarations:
value = resolved.get(key)
if value is absent and spec.required:
problems.add(key + ": required, searched defaults/file/process env/invocation")
else if value is absent:
resolved[key] = spec.default # declared, and echoed like any value
else if not spec.parses(value):
problems.add(key + ": expected " + spec.shape + ", got " + value)
if problems is not empty:
abort_run(problems) # all of them, once, before case onego deeper
Be ready to say that a run should stop and say what is missing rather than guess a value. Recall that an early, explicit failure is cheaper to fix than a failure discovered inside a case.
Explain the mechanics: keys are declared required or defaulted, validation runs once after resolution, presence and declared shape are both checked, and every problem is reported in one abort rather than one at a time.
Demonstrate that you have chosen a failure mode deliberately. Talk about the silent-green outcome, what a good abort message contains, and how a scattered wave of case failures gets misattributed to the product for hours.
Own the policy across an estate: which classes of key are never defaultable, how defaults stay reviewable as a list, and how you keep teams from adding fallbacks that quietly convert a broken run into a passing one.
## Two different wrong answers When resolution finishes and a key the run genuinely needs has no value on any layer, a suite can do one of two things. It can **abort**, printing what is missing, or it can **substitute** a built-in default and carry on. Both are failures of configuration. They differ in when the failure becomes visible and in who pays to diagnose it. Aborting costs one run and about ten seconds of a person's attention: the message names the key, the person supplies it, the run proceeds. Substituting costs whatever the run then does. In the lucky case the substituted value is wrong enough that cases fail, and the team spends a morning reading failure messages that blame the product for behaviour the product never exhibited. In the unlucky case the substituted value is *harmless* — an empty selection, a zero count, a permissive switch — and the run goes green having verified far less than anyone believes. Green-because-nothing-happened is the most expensive outcome in this whole area, precisely because nothing ever draws attention to it. ## Deciding which keys are required The declaration is a design act, made once per key, when the key is introduced. A key is **optional with a default** when one value is right in the great majority of situations and being wrong about it costs only time. A key is **required** when no value is defensible in the absence of a statement, either because a guess would be silently wrong or because a guess would do something irreversible. | Property | Optional, with a default | Required, aborts when absent | |---|---|---| | One value is right nearly everywhere | yes | no | | Cost of guessing wrong | some wasted time | a wrong verdict, or damage | | Who sets it | nobody, on most runs | some layer, on every run | | Typical examples | worker count, artefact location, batch size | the tenant a run may mutate, the build reference it reports | The examples are illustrative rather than universal. The same key can be required in one suite and defaulted in another, and that is fine as long as the choice is recorded beside the key rather than hidden in the code that reads it. ## Validate the whole set at once Validation belongs immediately after resolution and before the first case — the same single place the precedence chain already gave you. Two properties separate a helpful abort from an irritating one: 1. **Report every problem, not the first one.** A run that names one missing key, gets fixed, then names a second, then a third, is three round-trips instead of one. Collect all failures, then abort once. 2. **Check shape, not only presence.** A key that is present but unusable — text where a number is declared, a value outside the permitted set, a path that does not exist — is the same class of problem and deserves the same pass and the same message style. A good abort message carries four things: the key, what was expected of it, every layer that was searched, and how a person supplies it from the layer they are most likely standing in. Anything less converts a fixed-in-seconds problem into a puzzle someone reverse-engineers from the harness source. ## Where fallbacks legitimately live None of this is an argument against defaults. A suite with no defaults at all forces every run to restate values that never vary, which drives people to copy long invocations between each other and to stop reading them. The rule is narrower: **a default is a declared answer to "what if nobody says?", not a patch over a missing statement.** Two habits keep that distinction honest: - Every default lives with its key in one declaration, not scattered through the code that reads it, so the whole set of defaults can be reviewed as a list. - Every default appears in the echoed effective configuration exactly like a supplied value, so a reader never needs to know which values came from a person and which came from the declaration. ## How to recognise you already have this problem - Case failures that cluster on one machine or one job and disappear everywhere else. - A failure message that accuses the product and turns out, hours later, to be a value nobody set. - Defaults that can only be discovered by reading the harness, because no list of them exists. - A run that passes in a fraction of its usual time and nobody asks why. ## The trade the question is really about An interviewer asking this wants to hear that you **chose** a failure mode rather than stumbled into one. A suite exists to produce verdicts someone will act on, so the failure it should prefer is the one that is impossible to misread: loud, early, and unmistakably attributable to configuration rather than to the product. Silent fallback optimises for the run finishing, which was never the goal. A run that finishes and means nothing is strictly worse than a run that refuses to start.
- How do you decide whether a particular key deserves a default at all?Ask what a wrong guess costs. If one value is right nearly everywhere and being wrong costs only wasted time, a documented default is defensible. If a guess could be silently wrong, produce a verdict about the wrong thing, or do something irreversible, the key is required. Record the decision beside the key, so the whole set of defaults can be reviewed as a list rather than discovered by reading the harness.
- A key is present but unparseable, say text where a number was declared. Is that the same problem?Yes, and it belongs in the same validation pass with the same message style. Presence alone is a weak check: a value outside a permitted range, a malformed structure or an unparseable number all reach the first case as a failure that looks like a product defect. Checking declared shape at the same moment as presence keeps every configuration problem in one loud, early report.
- Why report every missing key rather than aborting on the first one found?Because a first-failure abort turns one fix into several round-trips: the person supplies one key, restarts, learns about the next, and repeats. Collecting all problems and aborting once makes a mis-set run a single correction. It also produces a better picture of what happened, since several missing keys usually point at one absent layer rather than at four unrelated mistakes.
saying these in an interview costs you the question
- Substitutes an empty value and lets cases fail later
- Thinks a green run proves the configuration was right
- Aborts on the first missing key and stops looking
- Checks that a key is present but never its declared shape
- Hides defaults in the code that reads each value