Day 1 of Run Explorer: Why a Missing File and a Quoted Six Fail in Different Places
I broke the starter on purpose. A missing import stopped the page. Passing the number six in quotes failed the typecheck and left the page on screen. Those two results are why the checks stay separate.
The short version
Run Explorer is an unofficial dashboard I am building in public. It reads the recorded steps of an application run and, later, writes a failure brief that cites those steps. The first application it will watch is Ask TanStack Query.
On Day 1 I set up the project and broke it twice. The page shows six synthetic runs. There is no API, no database, and no model call yet. The point of the day was to see which tool catches which mistake.
What I broke
Both mistakes were one line. I put each file back after I had read the error.
1. A file that does not exist
src/main.tsx is the file that mounts React. I changed its import from ./App to a file that is not on disk:
import App from './AppMissing'Vite stopped the page. The browser overlay and the terminal running the dev server said the same thing: Failed to resolve import "./AppMissing" from "src/main.tsx". Does the file exist?
The long stack under that line is Vite's own code. The useful line is the missing path.
2. A six in quotes
makeRuns builds the rows. Its count argument is a number. I called it with a string:
const runs = makeRuns('6')The editor underlined '6'. The production build stopped in the typecheck, before it wrote a bundle. The quotes are the whole mistake. 6 is a number. '6' is text.
Why the page died for one mistake and stayed up for the other
Vite's job in development is to serve the app. When the browser asks for src/main.tsx, Vite loads that file and every import it names. ./AppMissing is not on disk, so serving stops there.
TypeScript's job is to check shapes before the code runs. makeRuns(count = 24) requires a number. A string fails that check. TypeScript is then erased. The browser never sees the type.
The production build runs those as two steps, tsc --noEmit && vite build. The typecheck writes no JavaScript. If it fails, the && never starts the bundle. The dev server is a separate process. It kept showing the last good page while the bad call sat in App.tsx, and it could not show anything at all while the import pointed at a missing file.
npm test is another check. Six domain tests passed before I broke anything. They do not look at a missing import in the page.
The plan: record the run, then explain the evidence
A run is one execution of a workflow. A step is a named piece of it, such as retrieving documents. The dashboard reads those records. It does not rerun the original request or fix the failure.
The finished project follows five steps:
- Record: the application emits ordered events for each step
- Store: an API validates those events and saves them in Postgres
- Inspect: the dashboard filters runs and shows each step on a timeline
- Explain: a model writes a failure brief that cites step IDs, and separates what was recorded from what might have caused it
- Grade: known failure cases score those briefs before I trust them
Two rules are already in the data, even though the page is still a static table. A status is one of queued, running, succeeded, or failed. A missing duration is null. Zero would pretend the step was measured.
You can read the full plan on the Run Explorer case study.
What I set up on Day 1
Day 1 was four small commits. None of them is impressive on its own, and that is the point of building in public: the groundwork is part of the story.
- A README. The customer problem, what the dashboard will do, and the stack: React and Vite on the page, TanStack Query for server state, FastAPI and PostgreSQL for the recorded events, and OpenAI for the failure brief.
- Six runs on a page. The Vite, React, and TypeScript starter.
npm run devserves it,npm run buildtypechecks and writesdist/, andnpm testpasses six tests. No API key. - A formatting pass. Single quotes and line breaks across
App.tsx,main.tsx, andindex.html. No change in behavior. - A journal. The two breaks, in
JOURNAL.md, so I can say what each tool caught without rereading the terminal.
Why I broke it before I added anything
I want a record of what each check is for before the app has real features. A green page does not tell me where to look the next time something fails.
The missing file belongs to Vite. The quoted six belongs to TypeScript. Remembering that split is the whole lesson.
Frequently asked questions
What is a run in Run Explorer?
One execution of an application workflow, made of named steps. The dashboard reads the recorded facts. It does not run the application again.
Why is a missing duration null instead of zero?
The step has not reported a duration. Zero would be a real measurement of no elapsed time. null means the measurement is absent.
Why did the page stay up when makeRuns received a string?
The dev server and the typecheck are separate. Vite can keep serving the app while tsc rejects the call. npm run build runs the typecheck first and stops before bundling.
Is Run Explorer an official TanStack project?
No. It is an unofficial portfolio project. Its first customer is Ask TanStack Query. It does not rerun that app, edit the docs, or speak for the TanStack team.
Next up
Day 2 is the table itself. Real table markup, a button for each run, and a layout that still works on a narrow screen. You can read it in Day 2 of Run Explorer.
If you want to follow along, the repository is public and every day lands as a commit.
Related: Day 1 of Ask TanStack Query: Why AI Gives Outdated TanStack Query v5 Answers
