The mobile app worked for weeks, then would not build
The first release build of the mobile app failed on two configuration bugs weeks old. Development mode had never taken either code path.
The mobile app had been in development for weeks. It type checked, it bundled, its screens rendered under the development client, and its API calls were verified against a running server. All the checks the team could run said it was fine.
The first time anybody produced a release package, it failed twice before producing anything. If that first build happens the day before a demonstration or a store submission, you lose that day, and the weeks of green reports told you nothing about it.
What was actually going on
The first failure was the bundler resolving the wrong entry point. In a monorepo it had inferred its server root from the folders it was told to watch, which put the root above the application, so the embedding step went looking for an entry file two directories up. Development mode never took that path, because it starts a server with an explicit root.
The second was a build-time preset that the babel configuration required and that was not a direct dependency of the package. Under a package manager that links strictly, an undeclared dependency is simply absent. It had been resolving through the development server, which had it for its own reasons.
Neither was a new bug. Both had sat in the repository since the application was scaffolded, invisible because the code path that reads them had never run. Development and release are not the same program with a flag: they differ in entry resolution, transforms, dependency graph, bundling and signing.
Two obstacles were environmental and presented as something else. Process creation on Windows caps the command line at the legacy path length even with long paths enabled, so a deep dependency tree produced a failure that looked like a missing file. A native build then reported that it could not identify a C compiler, which sends you to install a toolchain you already have. It was the same limit, hit on the staging directory. Both went into a document in the repository, so the next occurrence costs five minutes.
What we changed
Installing the package on a real device was the first runtime verification the app had ever had. Every previous round had ended with an honest note that no screen had been driven on hardware.
That first device run checked three things: the package was installed and its main activity was in the foreground, the system log had no fatal errors, and the embedded bundle was searched for the API address it was compiled with, to confirm it pointed at the deployed server with no fallback to a local one.
The last check catches the worst class of release defect. A development fallback baked into a shipped bundle is invisible in source review, because the source is conditional and the condition looks right. It produces an app that works for everyone on the office network and for nobody else. Only the compiled artefact shows which branch was taken.
What it did not fix
The device run was the first, not a full test. Across those rounds the reports ended with the same plain sentence: type checked, bundled, every translation key resolved, every endpoint exercised against the live API, and never run by a person on hardware. Eleven kinds of static verification do not add up to one runtime execution, and the one not done is the one that finds an entry point resolving two directories up.
The same applies to other untried directions: a migration that has only run forward, a deployment script run by one person on one machine, a backup never restored. Each is unmeasured, not probably fine.
What to ask your own team or supplier
- Has a release build been produced yet, and when was the first one made?
- Has anyone installed the build on a real device and read what the compiled app points at?
- Which verifications have not been done, and does the status report say so in plain words?
- Has a restore from backup, or a migration in reverse, ever been run?
- When a tool reports something odd, such as a missing compiler, who checks whether it is true?
Where this ends up
Producing a release artefact in the first week rather than the last is part of the delivery method in AI-first delivery. Working increments mean the packaging is exercised while the configuration that breaks it is still small enough to read.