Dev Tools
Hands-on articles for building with Gemini developer tools — Gemini CLI, Code Assist, Google AI Studio, editor integrations, and test automation.
Stop Re-Reading Every Crash Report: Grep a Known-Bug Table First and Keep Only an Index in GEMINI.md
A routine for investigating app crash reports without making the model read every past bug in full: a one-line-per-bug lookup table, what belongs in GEMINI.md, and a grep helper you can paste in.
Three Veo 3.1 previews stop on Oct 22. I started with an inventory of every call site
Three Veo 3.1 preview models shut down on Oct 22, with gemini-omni-1.1-flash as the listed replacement. Before swapping model names, here is a search script that finds every call site in a repo, and a config pattern that stops loudly after the deadline instead of drifting to another model.
Gemini CLI Kept Saying 'API key not valid' After I Gave It a New Key — It Was Reading an Old One From a Third Place
I switched Gemini CLI from Google login to a paid API key, and the 400 'API key not valid' error would not go away. The key can come from four places — the shell, a project .env, a home .env, and settings.json — and a short script that lights them up in order narrows the cause to one.
The Day I Unplugged an MCP Server for the First Time — How I Decide Which Tools Stay On
Keep adding MCP servers and quality degrades well before you hit the API ceiling of 512 function declarations. Here is how I use includeTools and excludeTools in Gemini CLI to decide which tools stay enabled, and how I put the rest away.
The approval rules I had written never matched once — auditing my Gemini CLI policies
A deny rule I trusted for half a year had never matched. The pattern was tested against a JSON string, the folder I kept my rules in is not read, and ask_user turns into deny the moment nobody is watching. Here is the audit, and the script I wrote to keep doing it.
Matching name variants in a print catalog: normalize first, then ask Gemini for candidates
When the same artist appears under three spellings, asking Gemini whether two names are the same person quietly merges different generations. Here is the two-layer alternative — deterministic normalization first, model-generated candidates second — with working code and a cost estimate.
Icon-Only Buttons Can Stay Silent for Screen Readers, Even When Every Translation Is in Place
A fully translated app can still read as silence. Here is how I collect icon elements and labels from iOS and Android, settle everything mechanical locally, and send only the wording to Gemini — with the actual output from each stage.
When Gemini Let Me Upload Several Code Files at Once, I Stopped Selecting by Folder
Once you can hand Gemini a slice of a repository, the hard part moves from pasting to choosing. I measured the dependency graph of my own Next.js repo, found that folder-based selection caught zero callers, and wrote down the selection routine I use now.
An agreement-rate gate approves the model swap, then your category shares move
Swapping the model behind an image classification batch can pass a golden-set agreement gate while category shares quietly shift. I measured the sample sizes each check really needs and rebuilt the gate as a paired comparison.
Why Shipped Clients Deserve a Refusal, Not a Silent Model Substitution
A model can retire, but the apps already on people's phones cannot. This is how I built a sunset ledger keyed on output contracts, and how I now back-date my own deadline from the version residue curve.
A twice-daily batch that only ran once — reconstructing run counts from artifacts
One half of a scheduled job silently never fired, and throughput sat at half of plan for over a week without a single error in the logs. Here is how I reconstructed actual run counts from artifacts and backlog, with working code.
Turning Logging Off in AI Studio Also Turns Off Interactions API Conversation History
When no Gemini API logs show up in AI Studio, the usual culprit is the store default, which is inverted between the two APIs. Here is the side effect that quietly stops conversation history, and how to set store per request so it never surprises you.
Gemini quietly drops %1$s from translations, and no reviewer catches it
Format specifiers go missing, turn full-width, or get duplicated when Gemini translates app strings. Here are the four failure modes I keep seeing in production, how to stop them at generation time, and a short check that catches the rest.
The One Call I Refuse to Hand Gemini During a Phased Release
Day one of a phased release has nowhere near the sample size to tell a healthy build from a broken one. Here is the three-state rollout gate I use, and the narrow job I give Gemini inside it.
How Many Assistant-Dependent Lines Are Still in Your App?
On September 4th, Google Assistant on Android begins its replacement by Gemini. Here is how to grep your own project for every entry point an assistant can open, and how to turn that list into utterances you can actually test on a device.
Why My Length Limit Only Failed on the English Notifications, and the Width-Based Fit That Replaced It
I had Gemini write push notifications in Japanese and English, and only the English ones came out truncated on real devices. The culprit was measuring length in characters. Here are the measured widths and the post-generation fitting code that fixed it.
A minimal pre-send guard for Gemini-drafted app review replies
Store replies are risky after you hit send, not before. Here is a short Python guard that blocks unkeepable promises, leaked contact details, and register slips, plus the two false positives it produced on the first run.
Your Shipped App Still Remembers the Retired Model
Finishing the server-side migration is only half of a model retirement. The older builds of your app still hold the old model name, and once the cutoff passes, rolling back stops being a recovery option. Here is how I moved model resolution onto the server.
Before Adding New iPhone Widths, I Had Gemini Write Out the Branches I Already Had
Adding three new screen widths to four apps turned into an extraction job, not a rewrite. Here is why I let Gemini pull the branch table out of the source and kept every pass/fail decision in deterministic code.
Finding the questions your help docs never answer, by asking Gemini to write the quiz
When support keeps asking something your help page already covers, generate questions from that page and check whether the page alone can answer them. A two-pass audit pipeline with call design and cost math.
Green Tests, Dead Production — How Recorded Fixtures Hide a Model Retirement, and a Freshness Gate to Catch It
A test suite that replays recorded API responses will sail straight past a model retirement. I reproduce the failure in a minimal setup and build a cassette freshness gate, with measured overhead.
The Day I Stopped Tracking gemini-flash-latest: Batch Design That Survives Silent Model Swaps
A silent model swap pushed my batch rejection rate from 2.1% to 9.8% overnight. The pinning-plus-canary design I moved to, with the harness and numbers.
I Was Handing Gemini Obfuscated Stack Traces — Until retrace Went In Front, the Diagnoses Were Confident and Wrong
Release stack traces come out of R8 with the names flattened. Feed one to Gemini as-is and the diagnosis arrives calm, well-written, and wrong. Put retrace in front, match the mapping by versionCode, and forbid confident answers when you cannot restore. Numbers from 42 reports.
I stopped storing every generation log — three retention tiers and a prompt fingerprint that keeps traceability
I was storing every Gemini API request and response body for debugging. Here is how I moved to three retention tiers plus a prompt fingerprint, and kept the ability to diagnose issues without keeping the text.
Making TTS seams inaudible: prosody continuity and silence boundaries for long-form narration
Splitting a long article by sentence and synthesizing each piece leaves audible seams: prosody resets at every sentence start, clicks appear at PCM joints, and pauses feel uneven. Four layers -- context priming, zero-crossing edge fades, punctuation-aware silence, and an idempotent seam ledger -- make the joins disappear, with full code.
Never Generate the Same Narration Twice: Cache-Key Design and Invalidation for Gemini TTS Output
For apps that replay the same audio over and over—meditation, language learning, storytelling—caching the Gemini TTS output itself drives the variable cost to near zero. This is a working design: how to build a cache key that text alone can't cover, a two-tier server-plus-device cache, and an invalidation policy that survives model shutdowns like the August 17 image-model deprecation.
Closing the Failures That Never Throw: Normalizing Gemini API Responses into a Discriminated Union
An HTTP 200 with an empty body will never reach your catch block. Here is how I normalize finishReason and blockReason into a discriminated union, and let a never check turn missed cases into compile errors.
Stop Making Listeners Wait for the Whole File — Wiring Gemini TTS Streaming into Your Delivery Path
gemini-3.1-flash-tts-preview now streams audio via streamGenerateContent. A delivery path with 1.8s to first sound, covering PCM boundary handling, sentence-level resume, and a fallback for preview shutdown.
After the One-Click Deploy — Hardening an AI Studio Gemini App on Cloud Run for Real Production Use
AI Studio's one-click deploy to Cloud Run gives you a working URL in minutes — but not a production service. A practical checklist for API key storage, authentication, cost ceilings, and observability, with copy-paste gcloud commands.
Deleting the Source Isn't Enough — A Ledger Design for Propagating Deletes Through Gemini-Derived Data
When a user deletes their data, the embeddings, caches, and File Search documents you generated from it live on. A provenance ledger written at generation time, per-sink propagation workers, and a verification sweep make deletion actually reach your derived data.
url_context Still Answers When the Fetch Fails — Gating on Retrieval Status Before You Trust It
The url_context tool returns a confident answer even when it failed to fetch the target page. This walks through reading url_retrieval_status from url_context_metadata to build a verification gate, plus a fallback that only finalizes an answer when the source URL was truly read.
Building an AI-Powered Content Site with Gemini API and Astro
Combine Astro Server Endpoints and Content Collections with the Gemini API to add AI summaries, related-article recommendations, and auto-tagging.
Tracing Which Prompt Revision Moved Your Quality — Prompt Versioning for a Gemini Pipeline
Editing prompts in place erases the trail: when quality shifts you can't tell whether the model moved or your wording did. Here's a small system that pins prompts by content hash, stamps every generation with the model ID and revision, and bisects a quality drop down to the exact revision boundary, with copy-paste Python.
Gemini API × PWA Complete Implementation Guide — Service Workers, Offline AI, and Web Push Notifications for App Store-Quality Web Apps
Build production-grade AI web apps by combining Gemini API with Progressive Web App techniques — Service Worker caching, IndexedDB for AI context persistence, offline fallbacks, and Web Push notifications — plus instrumentation to surface API cost from your cache hit rate.
Gemini API × Android Jetpack Compose Complete Integration Guide — Production Design Patterns for Kotlin Native AI Apps
Build native Android AI apps with Kotlin and Jetpack Compose. Covers Google AI SDK, MVVM, multimodal chat UI, Room DB, WorkManager, and production security.
Folding a Local Gemma 4 into Daily Work — Practical Notes on the Ollama API and Response Speed
Taking a local Gemma 4 you can now run interactively and folding it into real work: how to hit Ollama's local API from a script, tricks to improve perceived response speed, and a two-tier fallback that automatically routes to the cloud Gemini API — code included.
Running Gemma 4 Locally on Windows — A Hands-On LLM in Two Commands with Ollama
How to run Google's lightweight open model Gemma 4 locally on a Windows laptop. With Ollama, you go from install to running in effectively two commands. Plus how to split work between the cloud Gemini API and a local Gemma.
Finding Every Reference to the Image Preview Models Before They Stop on June 25
gemini-3.1-flash-image-preview and gemini-3-pro-image-preview stop on June 25. Here is a dependency audit for surfacing references buried in rarely-run branches and batches before the cutoff.
Routing Gemini by Pipeline Stage: Draft on Flash, Finish on the Top Tier
A record of reworking which Gemini model handles which stage of an automation pipeline, prompted by the general availability of Gemini 3.5 Flash and the rollout of 3.1 Flash-Lite. Includes a small router that splits work into draft, classify, and finalize stages, how the cost picture changes, and the guardrails I settled on.
Keeping Nightly Batches Alive After the Gemini CLI Stops Responding: A google-genai SDK Fallback
On June 18 the Gemini CLI stops answering requests. Here is a small fallback harness that probes whether the CLI can still respond and quietly reroutes unattended batch jobs to the google-genai SDK, built from my own automation.