Your Agent Says It Deployed — Four Checks Before You Believe It
When your coding agent reports that it deployed your app, what it actually observed is that a sequence of tool calls returned without errors. That's a weaker claim than it sounds. The application status it read is container-level — it tells you a container is running, not that your code works — and there's no health check anywhere in the system that probes your app to find out. So an agent can truthfully report "running" for an app that crashed on startup, never bound its port, or is restarting in a loop. Four checks, in order, close the gap: did the build succeed, is the process staying up, is it listening where you bound it, and does it actually answer?
Why agents over-report success
Not dishonesty — a visibility problem. Your agent sees tool results. The tools report what the platform knows, and what the platform knows is narrow:
- Status reflects the container, not your process's health. If the container is up, status is up.
- Nothing probes your app. There's no
/healthpath being polled, no port check, no probe of any kind. - On a zip deploy, a crashed process doesn't stop the container. A supervisor restarts it every few seconds, so a crash-looping app reports as running indefinitely.
Put those together and "the app is running" is a statement about Docker, not about your software. An agent relaying it is being accurate about the wrong thing.
Check 1: did the build actually succeed?
Build output streams back as the deploy runs, and it's the one place a failure is unambiguous. Ask for it explicitly rather than accepting a summary.
Two failures worth naming because they're common and quiet:
- The build ran out of memory. Builds get roughly 0.75 GB, and a bundler or compiler can exceed it. The build stops mid-step with no clear error — easy for an agent to summarise as "the build finished".
- A build-time variable was empty. The build receives no environment variables and no build arguments, so anything inlined at build time —
NEXT_PUBLIC_*,VITE_*— becomesundefinedwithout failing the build at all.
Check 2: is the process staying up?
Ask for the last few dozen log lines and read them yourself. You're looking for one of two signatures:
- On a zip deploy,
!!! Process exited with code '<n>'. Restart after 5 secrepeating. That's a crash loop, and the exit code is your diagnosis. - On your own image, the container restarting repeatedly in the event history.
If your app crashes after connecting to Discord, stop it before debugging — every restart spends an IDENTIFY, and enough of them get your token reset.
A useful thing to ask your agent, since it can run commands in the container: have it print the process list. If your process isn't there, nothing else matters.
Check 3: is it listening where you think?
The classic silent failure, and the one an agent is least likely to catch, because every individual step looks correct.
Two things must agree: the port your app binds, and the port you bound in the panel. And your app must bind 0.0.0.0, not 127.0.0.1 — a loopback binding is reachable only from inside its own container, so the router in front of it gets nothing.
EXPOSE 3000 in a Dockerfile does not create a binding. It's image metadata. An agent that sees EXPOSE and concludes the port is published is making a very common mistake.
Ask it to check from inside the container:
curl -sv http://127.0.0.1:8000/ | head
If that works and the public URL doesn't, it's a binding or interface problem. If it fails, your app isn't serving at all.
Check 4: does it answer from outside?
The only check that proves anything. Open the app's URL, or ask the agent to fetch it, and confirm you get the response you expect — not just a 200 from something, but your actual content.
Worth checking a real route, not just /. Frameworks often serve something at the root while the interesting paths 404, and single-page apps famously work until you refresh a deep link, which needs a fallback rule.
Ask for evidence, not conclusions
The habit that fixes most of this is changing what you ask for. "Did it deploy?" invites a summary. Ask instead for artefacts:
- "Show me the last 50 log lines, unedited."
- "What exit code is in the event history?"
- "Run
curl -s -o /dev/null -w '%{http_code}' <url>and show the output." - "List the environment variables the app has set." (Names are enough — see below.)
- "Run
psinside the container."
Raw output is checkable. A conclusion isn't. This costs you fifteen seconds and catches the entire class of "I've fixed it" that hasn't been fixed.
One caution while you're doing this: reading environment variables puts your secrets into the conversation, and that transcript is now sensitive. Ask for variable names rather than values unless you specifically need a value.
Three claims to treat as unverified
Phrases that are usually technically true and practically misleading:
| The claim | What it actually means |
|---|---|
| "The app is running" | A container is up. Your process may be crash-looping inside it. |
| "The port is exposed" | Possibly just EXPOSE in the Dockerfile, which publishes nothing. |
| "The environment variables are set" | They exist at runtime. They were not present during the build. |
A verification prompt worth keeping
Paste this after any agent-driven deploy:
Verify the deploy without assuming success. Show me: the last 40 log lines verbatim; the app status and any exit codes from the event history; the output of curling the public URL with the status code; and the output of curling the app's port from inside the container. Don't summarise — show the raw output, then tell me what it means.
The value isn't the checks themselves; it's that raw output makes an unsuccessful deploy visible instead of narratable.
FAQ
Why does my app show as running when it doesn't work?
Status reflects whether the container is running. On zip deploys a supervisor restarts a crashed process without stopping the container, so a crash loop still reads as running.
Does the platform check whether my app is healthy?
No. There are no health checks or probes. Restarts are triggered by a process exiting, not by a failed check.
Why did my agent say the build succeeded when it didn't?
Build failures from memory limits stop mid-step without a clear error, and a summarising agent can read that as completion. Ask for the build output.
What's the fastest way to confirm a deploy worked?
Fetch the public URL and check you get your actual content. Everything else is a proxy for that.
My env vars are set but the frontend can't see them.
Build-time inlined variables aren't affected by runtime settings — the build receives neither environment variables nor build arguments.
Should I let my agent read my environment variables?
Only when you need a value. Reading them puts your secrets into the conversation and into whatever you later paste it into.
Wrapping up
Agent-driven deploys are genuinely faster, and the failure mode they introduce is confident narration of an outcome nobody checked. The platform contributes to this by design — no probes means nothing contradicts an optimistic summary. So keep the loop tight and evidence-based: build output, logs, a request from inside the container, a request from outside. Four artefacts, under a minute, and the difference between deployed and deployed stops being something you find out from a user.