When does WireMock standalone read the stub files under its root directory?
answer
- once, on the way up
- disk and memory are two things
- the process is the unit of reload
- a bind mount is not a reload
- restart, or call the admin API
basics
~20 sThe read happens as the process starts: WireMock standalone builds its stub set from mappings and __files under the root directory. A file written afterwards is not served until a restart. Changing a running server is an admin API call.
solid answer
~40 sThe standalone launcher builds its stub set from the root directory as the process comes up, and then serves from what it read. Drop a new `mappings/inspection-overdue.json` into the root of a running server and `GET /v1/scaffolds/SC-4471/inspections/overdue` still answers 404: the file exists on disk and is not part of the loaded set. The straightforward fix is to restart the process — or `docker restart` the container, which is the same thing — because the read happens again on the way up. Changing what a running instance serves without a restart is a call on the server's own admin API rather than a file-system event, and stubs created that way live in memory, not in `mappings/`. Knowing which of the two you are using explains most surprises about a stub that is *definitely there*.
code
bash · 8 linesjava -jar wiremock-standalone.jar --port 8089 --root-dir ./scaffolding-inspection-stubs &
cp inspection-overdue.json ./scaffolding-inspection-stubs/mappings/
curl -si http://localhost:8089/v1/scaffolds/SC-4471/inspections/overdue | head -1
kill %1
java -jar wiremock-standalone.jar --port 8089 --root-dir ./scaffolding-inspection-stubs &
curl -si http://localhost:8089/v1/scaffolds/SC-4471/inspections/overdue | head -1go deeper
Remember that WireMock standalone reads mappings/ and __files/ when the process starts. A file added later is not served until you restart, however clearly it exists on disk.
Explain why a bind mount makes the file change instantly while the served set does not change at all, and name the two ways to move a running instance: restart, or the admin API.
Use it as a diagnostic: when a stub is definitely present and still 404s, ask whether the process predates the file before spending any time on the matcher.
Set the rule that a stub set has one source of truth. A long-lived instance patched over HTTP while a directory claims to define it is a state nobody can reproduce from the repository.
## The read happens once, on the way up WireMock standalone resolves its root directory — `--root-dir`, or the working directory when the flag is absent — and builds a stub set out of `mappings/` and `__files/` beneath it as the process starts. From then on the server answers from that set. The files on disk and the set in memory are two different things that happened to agree at one moment. That is easy to miss because both halves feel live. A bind mount is not a copy, so editing `mappings/scaffold-inspections-list.json` on the host changes the bytes inside the container instantly; `cat` proves it. What did not change is the stub set the running server is serving from. ## What that means for a mounted set The symptoms are specific and, once you know them, unmistakable: - A mapping you just added answers 404 while every older mapping works. - A mapping you just corrected keeps serving the old body, including the old `verdict` value. - A mapping you deleted keeps answering, because it is still in the loaded set. - The same stub set behaves correctly on the next pipeline run, because that run starts a fresh process. The last one is what makes the confusion durable: the problem cannot be reproduced by re-running the job, so it gets written off as flakiness rather than diagnosed. ## Two ways to change what a running server serves 1. **Restart the process.** The set is rebuilt from the root, so whatever is on disk becomes what is served. This is the honest option for a file-backed set and the only one that keeps disk and memory in agreement. 2. **Call the server's own admin API.** A running WireMock accepts changes to its stub set over HTTP, and those changes take effect immediately. They are also in-memory: a stub created that way does not appear in `mappings/`, and a restart returns the server to whatever the files say. Mixing the two is where teams get hurt. If a suite edits a running instance over the admin API *and* the directory is the source of truth, then the set that is serving and the set in the repository have quietly diverged, and only a restart reveals by how much. ## Why the once-only read is usually what you want A stub server that reloaded on every file change would be unpredictable in exactly the wrong place. Consider a build agent where one job rewrites the scaffolding-inspection stub directory while another job's tests are mid-flight: with a start-up read, the running job keeps the set it started with and finishes deterministically. Reading once turns *which stubs are in play* into a property of the process, fixed for its whole lifetime, and a fixed property is something a test result can be attributed to. It also matches how the set is deployed. In a container the stub directory arrives with the container and leaves with it, so the process lifetime and the set's lifetime are already the same span. Making the read follow the process rather than the filesystem keeps those two aligned. ## The habit that avoids the confusion - Treat the container, or the process, as the unit of reload: edit the mapping, restart, retest. - Keep the restart cheap. A named container and a one-line script mean the loop costs a couple of seconds and nobody is tempted to hand-patch a running server. - Decide, per suite, whether the directory or the admin API is the source of truth, and do not use both at once for the same stub. - When a mapping is *definitely there* and still 404s, check whether the process predates the file before you touch the matcher. - Prefer restarting to hand-editing when the set is committed: a hand-patched instance is a state nobody else can reproduce from the repository. ## How the neighbouring products frame the same moment The once-at-start-up read is not unique to WireMock, and the vocabulary differs enough to trip people who move between products. In Mountebank, the imposters named by `mb --configfile` are likewise read as the process comes up, and later changes to a running instance go through its own control surface rather than through the file. The shared lesson is worth stating plainly: on every one of these servers, the file on disk configures *the start of a process*, and the running instance is changed over HTTP or not at all. ## What this is not It is not a claim about mapping content, matching or precedence — a stub that loaded and did not match is a different investigation with different tools. And it is not an argument against file-backed stub sets: a directory in the repository, read once as the server starts, is the most reviewable and most reproducible shape a stub set takes. The only thing it asks of you is that you notice which moment the read happened at.
- A stub file is definitely present and the server still 404s it. What is your first check?Whether the process is older than the file. WireMock built its set as it started, so anything written afterwards is on disk and not in the loaded set. Restart and retry before touching the mapping: if it answers after the restart, the mapping was always correct and the read moment was the whole story.
- Why can changes made over the admin API disappear?Because they are held in memory by the running instance rather than written into `mappings/`. Restart the process and the set is rebuilt from the root directory, so anything that existed only in memory is gone. That is a feature when the directory is the source of truth, and a trap when a suite has been quietly patching a long-lived instance.
saying these in an interview costs you the question
- Expecting a running server to notice a new mapping file on its own
- Confusing a live bind mount with a live stub set
- Editing a running instance and assuming the change survives a restart
- Blaming a matcher for a mapping the process never loaded
- Treating the same set as file-backed and admin-managed at once