DEV Community

Phil Rentier Digital
Phil Rentier Digital

Posted on • Originally published at rentierdigital.xyz

Claude Code Now Lets You Code From Your Phone. Here's What I Learned the Hard Way.

I was in a taxi heading to the beach when the Vercel email hit.

Production down. Deployment failed.

I stared at my phone for a second. Then I remembered: Claude Code has a web version now. Works from mobile. I'd been meaning to try it.

So I did the reasonable thing. I opened Claude Code web, described the error, and watched an AI agent fix my production system while I was literally on my way to go swimming.

Three minutes later: fix done, branch pushed, PR ready.

I merged it from GitHub mobile.

Viva la Vida. 😎

Then I put my phone down and went to the beach. Because that's what you do when an AI is running your infrastructure.

Ten minutes later, Vercel sent another email.

TL;DR: Yes, Claude Code Web lets you fix production from your phone. Yes, I tried it from a taxi. Yes, it "worked." The rest of this article is what happened next.

[cover image]


Here's the thing I did not do before merging: run git diff. Or npm run build. Or literally anything that would have taken thirty seconds and saved me forty minutes.

In my defense, I was in a taxi. And the fix looked reasonable. Three files modified, one clean commit message. What could go wrong.

(Everything. Everything could go wrong.)


The Container Doesn't Live in Your Project

Let me explain what Claude Code web is actually doing when it takes a task, because the demos make it look like magic and it's not (it's something more interesting and more limited at the same time).

When you submit a task, Claude Code web spins up a fresh isolated cloud container, clones your repository into it, and starts working. What it has: your code. What it doesn't have: your .env file, your local packages, your specific framework version, your deployment configuration, and any context from commits that happened before it showed up.

It reads your files. It runs commands. It observes the errors those commands produce. Then it fixes what it sees.

The mismatch is subtle enough that it's easy to miss. The AI isn't wrong (it's diagnosing from a different environment than the one where your code actually runs). Its fixes are coherent. They're just coherent with a context that doesn't match yours.

Think of it like sending a photo of your broken bike to a mechanic over WhatsApp. He looks at it, says "it's the chain." You replace the chain. The bike still doesn't work. The actual problem was the brake cable (not visible in the photo). Was the mechanic incompetent? No. He worked with what he could see. The rest was invisible to him.

Claude Code web is the mechanic. Your repo without environment context is the photo. Your actual production bug is the brake cable.

In my case, this played out with impressive precision.


A Tour of My Phantom Fixes

Here's what the sandbox documented in its own session, and here's what was actually going on:

Fix #1: The font package swap.

The sandbox noted: "The most likely deployment issue is the Google Fonts fetch failing during the Turbopack build. Switching to a locally bundled package avoids network requests during build."

Completely logical. In an isolated container with restricted outbound network access, fetching fonts from an external CDN at build time fails. So it switched to a locally bundled alternative. Smart.

In my actual production environment, the original import works perfectly and has been working for months. The sandbox fixed a problem I have never had, using a dependency I had never installed. Cool. Thanks.

Fix #2: The placeholder URL.

Missing environment variable in the container → client crashed at build time → solution: add a fallback to a dead cloud URL so the build doesn't break.

In production, the real variable exists. So the fallback would silently do nothing, unless the variable ever went missing (at which point the app would quietly connect to nowhere instead of crashing loudly).

Great. A fix that works correctly in an environment that doesn't exist, and degrades silently in an environment that does.

Fix #3: The lazy initialization.

This one was actually correct. Instantiating a client at module load time causes real issues with static prerendering, regardless of env vars. The refactor to lazy initialization is genuinely better practice.

One out of three. I'll take it.

None of the three touched the actual reason my deployment was failing.


The Real Bug (It Was an Icon)

A few commits before all of this, I had added a custom favicon. A small file, dropped into a directory where the framework was running. What I didn't know: in my framework version, placing a file with that specific naming pattern in that directory makes it get treated as a route handler, not a static asset. The build had been silently broken since that commit.

The sandbox never mentioned it. Why would it (the errors in its build logs were the font fetch and the missing env var). The icon issue was producing a different kind of failure, one that only shows up in a specific build environment. Invisible from the container.

When I finally sat down at my laptop and ran a local build, the output pointed directly at the icon file. Thirty seconds to identify. Five minutes to fix.

That fix is not in the sandbox branch. Couldn't be. The sandbox had no idea it existed.

So to recap: I merged a branch that added a dependency I didn't need, introduced a silent failure mode, and correctly refactored one thing (while the actual cause of my production outage sat untouched, waiting for me to open my laptop like an adult).


The Revert (Yes, I Had to Revert the Fix)

The locally bundled font package wasn't in my original dependencies. The sandbox had added it. So after merging, running a local build produced a brand new failure: package listed as a dependency, not actually installed.

I pulled the original layout file from git history. Removed the new package. Reinstalled. Reverted the placeholder URL back to a hard crash on missing env var (because if that variable ever disappears in production, I want a loud explosion, not a polite connection to nothing).

Kept the lazy initialization. That one earned its place.

Commit. Push. Clean deployment.

Total elapsed time between "laptop stays closed" and "laptop closes again": forty minutes. The beach was fine. The debugging was not.


Three Rules That Actually Hold

Treat every sandbox branch like code from someone who's never run your project.

Not because the AI is bad at its job. Because it literally has not run your project (it's run a reconstruction of it, missing the parts that live outside your repository). Review the diff. git diff main..origin/branch-name is fifteen seconds. If you see a new package, a fallback URL, a dependency you didn't put there (the sandbox was compensating for something it didn't have). Figure out whether that something is real before it ships.

Run a build locally before merging anything near build config.

npm run build. Or whatever gets you close to your actual deploy environment. This single step would have ended my entire adventure before it started. The phantom font fix would have failed immediately (package not installed). Thirty seconds of terminal output beats forty minutes of post-merge archaeology.

The three minutes this adds to your workflow is not the bottleneck. You know this. Admit it.

Give the sandbox your environment before you hand it a task.

Claude Code web's task creation screen has an environment variables field. Paste your actual env vars there. The container now runs with something that resembles your real context. Most phantom fixes disappear. The agent stops solving problems you don't have and starts solving the one you actually do.


The Honest Version of the Dream

Let's talk about the "code from anywhere" fantasy for a second.

Nobody actually wants to debug a production failure on a beach. That's not a dream, that's a punishment. Squinting at a phone screen in direct sunlight, sand in your keyboard, trying to understand a stack trace. That's a nightmare with good lighting.

The real dream is different. Being able to queue something and walk away. Start a refactor, leave it running, come back to a result. That part works. Claude Code web handles self-contained tasks cleanly (anything where cloning the repository gives the agent everything it needs). Writing tests. Cleaning up a component. Updating documentation. Renaming things. Tasks that live entirely in the code, no env vars required, no build environment quirks.

The taxi-to-beach workflow breaks down specifically when the problem is environmental. Which, as it turns out, production deployment failures often are.

Queue the task. Go to the beach. Come back and review the diff on your laptop like a professional.

That's the actual dream. The rest is a tweet waiting to happen. 😬

Same underlying principle as vibe coding without constraints: an AI works coherently inside whatever context it has. Give it an incomplete one, and you get coherent solutions to the wrong problem. Env vars in the sandbox, local build before merge, git diff before approve (same move every time). You're not fighting the AI. You're giving it your reality instead of a photocopy.


In six months, some devtool will ship "intelligent sandbox context sync" as a premium feature. There'll be a waitlist. The onboarding email will say "code from anywhere."

The developers who already run a local build before merging won't need it.
They already know what the container can't see.
They already went to the beach. Without their laptop. On purpose.

That's the actual future of dev.


Resources: Claude Code documentation — Anthropic sandboxing guide

I write about building production systems with AI tools (the parts that don't make it into the launch threads). No schedule, no filler. Drops when there's something worth saying.

(*)The cover is AI-generated. I could have gone to the beach instead of prompting it. In retrospect, that would have been the smarter call.

Top comments (1)

Collapse
 
klement_gunndu profile image
klement Gunndu

The WhatsApp mechanic analogy is perfect. Ran into the same thing — sandbox-generated fix passed its own tests but broke locally because it couldn't see the .env-dependent config. Now I never merge without git diff first, even from mobile.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.