ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-04-23Advanced

Designing Antigravity Browser Agents That Don't Go Flaky — Taming DOM Drift and Timing

A browser-agent task that passed yesterday trips today, then succeeds on retry, then fails again. Here's how I've been breaking down the causes of flaky Antigravity browser agents in production and addressing them at the design level.

Antigravity321Browser AgentFlakinessE2EOperations8

When you start running browser agents in production, the first wall you hit is: "it passed yesterday and it's failing today." Antigravity is getting smarter, but the counterpart is the live web, and the web doesn't care about your plans. In both my own apps and a couple of automation gigs I help with, this flakiness has pushed me to the edge more than once.

This article walks through concrete tactics for designing Antigravity browser agents as if they will fail — and making sure that when they do, nothing important breaks. The specifics vary by project, but the mental model translates to other agent frameworks too.

Sort the Kind of Flakiness First

First, understand that "flaky" tasks usually come from three distinct root causes. Bundling them together and "just adding retries" papers over the symptoms.

  • DOM structure drift: A/B tests or small redesigns ship on the target site. Yesterday's selectors no longer match today's markup.
  • Async loading timing: The page is painted, but the element the agent needs hasn't been injected by JavaScript yet.
  • Network / session jitter: An auth token expired, a CDN edge served stale content, or bot detection rerouted you.

Early on, my bots treated these as one bucket called "it broke." Once I forced the logging to be useful, the split landed around 40% DOM drift, 40% async timing, 20% network jitter. Treatment priority changes depending on the split, so classification must be instrumented from day one.

At minimum, capture the pre-failure DOM snapshot, the failing step's prompt, and the round-trip timing of the failing call. Put them in your own log pipeline, not just Antigravity's. A week later you can actually draw a bar chart and pick the right thing to fix next.

Don't Hand Selectors Off to the Agent

DOM drift is the biggest source of flakiness. Antigravity's browser agent is pretty good at re-inferring an element from the surrounding context when a class name changes. But whether that re-inference succeeds is up to the target site. A concrete case I hit: after an e-commerce site dropped a limited-time promo button next to "Add to cart," the agent started clicking the wrong button on a noticeable share of runs.

My safer approach is to specify a semantic anchor in natural language, not a selector directly, using domain vocabulary:

On the product detail page that's currently open, click the button that
semantically means "add this item to the cart."
Do NOT click limited-time campaign buttons or coupon-acquisition buttons.
If ambiguous, prefer the button whose visible text exactly matches one of:
"Add to cart", "ADD TO CART", "カートに入れる".

Two design choices matter. First, the developer enumerates the candidate texts. Second, you explicitly list what not to click. A short negative list cuts accidental clicks on A/B-inserted buttons dramatically.

For stricter workloads, I also ask the agent to capture a screenshot of the target element and its ±100px neighborhood before clicking. That residue is a lifeline when something looks off days later.

Wait on State, Not on Time

Next up: async loading. Early on I leaned on fixed sleeps equivalent to time.sleep(2). They pass the day you write them and fall apart the first slow-network day.

For Antigravity, I write state-based wait conditions instead of timed waits:

After submitting the login form, wait until ALL of the following hold:
- The URL path is either /dashboard or /home
- The page contains a text node containing "Welcome, " or "ようこそ、"
- There are zero elements with aria-busy="true" on the page
 
Wait at most 20 seconds. If the condition is not met, raise an error and exit.
If spinners are still present at timeout, attach a screenshot.

By dropping fixed sleeps, the agent moves fast on fast networks and patiently on slow ones. The critical part: don't wait on a single condition, AND multiple conditions together. URL-change alone gets fooled by SPA partial routes. Text-presence alone misses diff rendering. Only the conjunction reliably says "we've actually reached the next screen."

Waits need maintenance because targets redesign. I keep them in a separate file (waits.yaml-ish) that the task prompts reference. When the site changes, the place to edit is obvious, and review stays easy.

Retry Smart, Not Blind

No matter how carefully you write them, browser-agent tasks will never be zero-flake. You need a retry strategy, but blind retries expand the damage. I pair every retry with idempotency.

The rules I run:

  • Retry only steps that are side-effect-free or idempotent.
  • Steps with side effects (payments, form submissions, outbound emails) must notify a human on first failure before any re-attempt.
  • Retry intervals use exponential backoff (1s → 3s → 10s).
  • After three consecutive failures in a day for the same task, stop retrying that task for the day.

The last one looks conservative but matters. When the target site is briefly broken, blind retries nudge the site's bot detection into labeling you. Cutting off at three keeps your IP reputation alive.

Snapshot Prompts for Reproducibility

Another habit that pays off: snapshot the prompt and the result for every run. With Antigravity, identical prompts can exhibit small variations run-to-run — that's the nature of the model. Knowing exactly which prompt, which model, and which inputs produced a given result is what turns a multi-hour forensic from into a 15-minute one.

Per run, I store:

  • The full final prompt that was sent (not the template — the rendered version)
  • The model and version
  • The URL and an outline of key elements on the input page (headings, key button/input text)
  • Pass/fail status, plus screenshot and HTML dump on failure

With this residue, when a task suddenly starts failing a week later, you can narrow hypotheses to two or three in minutes. Without it, you re-run the same prompt and pray for another failure to study. Time evaporates.

What You Can't Observe, You Can't Fix

This goes beyond browser agents, but don't skimp on observation. Track, per task, per day:

  • Success rate (successes / attempts)
  • Average steps per run
  • Average wall time per run
  • Failure cause distribution (selector miss, wait timeout, HTTP error, other)

A chart makes "flakiness is creeping up" visible before a user tells you. Gut feel lags, often by weeks. Even in a solo project, half a day spent wiring a tiny dashboard is among the highest-ROI time I know.

Design for "Breaks Painlessly," Not "Never Breaks"

Used well, Antigravity's browser agent quietly shoulders a lot of life admin. But you're dealing with a web that changes on its own schedule. Designing as if nothing will break is what burns you out.

What I stick to, both personally and when helping others: design for "breaks painlessly." Assume DOM drift will come and write semantic anchors. Wait on state, not clock. Separate retries by side-effect and idempotency. And always leave snapshots of what happened. With that bundle, flakiness becomes a background cost you can absorb rather than fight.

If browser agents are bleeding time for you today, start by auditing what gets captured on failure. Once the cause distribution is visible, the order of fixes chooses itself.

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Agents & Manager2026-06-21
Keeping Unattended Agent Run Logs Long Enough to Debug — Without Filling the Disk
A scheduled agent is only fixable if you can reconstruct why it failed. Here is how to keep run logs around without filling the disk — tiered retention, schema-versioned records, and a compaction job — drawn from running four sites on autopilot as an indie developer.
Agents & Manager2026-04-29
Teaching Antigravity Agents to Learn from Failure — A Solo Developer's Loop for Reusing Failure History
Antigravity agents repeat the same mistakes because each session starts blank. A solo developer's six-month run with a structured failure log, a separate observer agent, and the side-effect of overfitting.
Agents & Manager2026-04-27
Letting Antigravity Be Your Night-Shift Engineer: A Solo Dev Operating Model
How to operate Antigravity agents as the second engineer who works while you sleep. Task hand-off, scope boundaries, and a five-minute morning review — the model I have refined while running multiple products solo.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →