GEMINI LABJP
PRICE — Gemini 3.6 Flash drops output tokens from $9.00 to $7.50 per million while input holds at $1.50, so verbose workloads feel the difference mostDEFAULT — The Antigravity agent in Managed Agents now runs on 3.6 Flash by default. Setups that never pinned a model may behave differentlyVERBOSE — 3.6 Flash answers the developer complaint that 3.5 Flash rambled, tightening token efficiency and agentic planning at the same timeGROK — The Grok 4.1 model family on the Gemini Enterprise Agent Platform is deprecated and shuts down on August 20CLASSROOM — From August 10, students of all ages in K-12 and higher education can use Gemini in Classroom where admins have granted access, turning materials into flashcards and quizzesPIXEL — Google's August 12 event is expected to fill in the Pixel 11 hardware details along with AI features across the wider ecosystemPRICE — Gemini 3.6 Flash drops output tokens from $9.00 to $7.50 per million while input holds at $1.50, so verbose workloads feel the difference mostDEFAULT — The Antigravity agent in Managed Agents now runs on 3.6 Flash by default. Setups that never pinned a model may behave differentlyVERBOSE — 3.6 Flash answers the developer complaint that 3.5 Flash rambled, tightening token efficiency and agentic planning at the same timeGROK — The Grok 4.1 model family on the Gemini Enterprise Agent Platform is deprecated and shuts down on August 20CLASSROOM — From August 10, students of all ages in K-12 and higher education can use Gemini in Classroom where admins have granted access, turning materials into flashcards and quizzesPIXEL — Google's August 12 event is expected to fill in the Pixel 11 hardware details along with AI features across the wider ecosystem
Articles/Dev Tools
Dev Tools/2026-08-05Intermediate

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.

Gemini API204pytest3testing3model retirementCI6

Premium Article

After reading through the August deprecation cluster in the changelog, I ran my local test suite. Six tests, all green, 0.11 seconds. Under that green sat three recorded responses from a model that stops serving on August 17.

In my solo app project, where I have been evaluating an image generation pipeline, every Gemini API test replays a recorded response — a cassette — instead of hitting the network. That is a reasonable design; nobody wants CI billing them per run. But for one specific failure class, model retirement, the same design actively works against you.

A passing suite and a production system that still works next week are two different claims. I spent a day wiring them back together, and measured what it cost.

What stops in August, and why mocks are structurally blind to it

First, the context. August 2026 is unusually dense with shutdowns.

WhatDateImpact
Imagen 4 family (imagen-4.0-generate-001 / ultra / fast) and the Gemini 3 Image familyRetires 2026-08-17Image generation pipelines must migrate
Grok 4.1 family on Gemini Enterprise Agent PlatformRetires 2026-08-20Agent configs need replacement
gemini-robotics-er-1.6-previewRetires 2026-08-31Preview-dependent paths need a fallback
3.5 Flash in Gemini Enterprise (global region)Removed 2026-08-04The model silently leaves the picker

Dates and scope can shift, so verify against the model deprecation schedule before acting on any of this.

Now consider how most of us test API integrations. Recorded replays, SDK mocks, stub servers — different names for the same move: freezing whatever is on the other side of the network. Latency jitter disappears from your tests. So do rate limits. And so does a model ceasing to exist.

Model retirement fits precisely into the class of failures mocks are designed to hide. The more thoroughly you mock, the later you find out. That inverse relationship is the uncomfortable core of this article.

Reproducing the green-but-dead state in a minimal setup

A working example beats an abstract warning. Here is a minimal client, modeled on a wallpaper app's generation path.

# client.py
import os
import requests
 
BASE_URL = "https://generativelanguage.googleapis.com/v1beta"
 
class GeminiImageClient:
    def __init__(self, model: str, api_key: str | None = None, base_url: str = BASE_URL):
        self.model = model
        self.api_key = api_key or os.environ.get("GEMINI_API_KEY", "")
        self.base_url = base_url  # injection point: tests aim this at a stub
 
    def generate(self, prompt: str, aspect_ratio: str = "9:16") -> dict:
        url = f"{self.base_url}/models/{self.model}:predict"
        resp = requests.post(
            url,
            params={"key": self.api_key},
            json={"instances": [{"prompt": prompt}],
                  "parameters": {"sampleCount": 1, "aspectRatio": aspect_ratio}},
            timeout=30,
        )
        resp.raise_for_status()
        return resp.json()

The test side replays recorded JSON by patching requests.post.

# tests/conftest.py (replay part)
import json
import pathlib
import pytest
 
CASSETTE_DIR = pathlib.Path(__file__).parent / "cassettes"
 
class _FakeResponse:
    def __init__(self, payload, status=200):
        self._payload = payload
        self.status_code = status
    def raise_for_status(self):
        if self.status_code >= 400:
            import requests
            raise requests.HTTPError(f"{self.status_code}")
    def json(self):
        return self._payload
 
@pytest.fixture
def replay(monkeypatch):
    def _use(cassette_name):
        data = json.loads((CASSETTE_DIR / cassette_name).read_text())
        def fake_post(url, **kwargs):
            return _FakeResponse(data["response"], data.get("status", 200))
        monkeypatch.setattr("requests.post", fake_post)
        return data
    return _use

Each cassette keeps its recording timestamp and request metadata. That decision pays off later.

{
  "recorded_at": "2026-06-20T09:12:44+09:00",
  "request": {
    "model": "imagen-4.0-fast-generate-001",
    "endpoint": ":predict",
    "parameters": {"sampleCount": 1, "aspectRatio": "9:16"}
  },
  "response": {
    "predictions": [{"bytesBase64Encoded": "iVBORw...", "mimeType": "image/png"}],
    "modelVersion": "imagen-4.0-fast-generate-001"
  }
}

On top of this I wrote six tests — prediction shape, image bytes, aspect ratio, batch output, the empty-predictions case for safety-filtered prompts. On my sandbox VM (Python 3.10.12):

$ python3 -m pytest tests/ -q
......                                                                   [100%]
6 passed in 0.11s

All green. Meanwhile, the recorded model, imagen-4.0-fast-generate-001, retires on August 17. Since the post-retirement behavior cannot be observed yet, I stood up a local stub that mirrors the NOT_FOUND shape returned by previously retired model families, and compared:

imagen-4.0-fast-generate-001: HTTPError 404 Client Error: Not Found (4.1ms)
gemini-3.1-flash-lite-image:  OK modelVersion=gemini-3.1-flash-lite-image (2.2ms)

The suite passes in 0.11 seconds; the same code against a live-shaped endpoint dies with a 404. That gap is what "green but dead" means. For what actually happens when production keeps retrying a retired model, I measured it separately in Retired-model retries never show up in your success latency — permanent errors have a way of hiding from healthy-path metrics too.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A minimal, complete reproduction of the failure mode — six green tests sitting on top of a dependency that retires on August 17, with full client, replay conftest, and cassette code
A cassette freshness gate that runs before pytest collection, measured at a median 7.1ms for 200 cassettes (n=50) on a sandbox VM
How to choose WARN_DAYS and MAX_AGE_DAYS, and a staged rollout that surfaces real migration work without burying your team in 101 sudden failures
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini 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 →

Related Articles

API / SDK2026-06-29
Guarding Gemini API Responses in CI: Snapshot and Semantic Regression Testing
How to defend non-deterministic Gemini API responses with pytest snapshot tests plus embedding-based semantic regression detection — including CI wiring, separating flakiness from real regressions, and snapshot-update governance, all in working code.
Dev Tools2026-07-25
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.
Dev Tools2026-07-18
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.
📚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 →