You found the perfect code snippet online. It promises to solve your RAG problem or nail that complex prompt. You copy the model name—say, gemini-1.5-pro—into your environment, you hit run, and BAM! “404 Model Not Found.” The model was updated to gemini-1.5-pro-002 overnight, or maybe it just disappeared. It’s frustrating, right?
This kind of instant obsolescence is the silent workflow killer in the world of Generative AI. You aren’t dealing with static software; you’re interacting with rapidly evolving services. Luckily, there’s a simple, elegant solution: a “sanity check” script that pings Google directly and asks, “What models are you actually serving today?”
Why Do We Need This Script?
The core issue boils down to the nature of cloud-based AI. Unlike traditional software, where version numbers are fixed for months or years, large language models (LLMs) are constantly being tuned, renamed, or retired without a formal v1.0 tag to keep things tidy.
The Problem of “Model Drift”
AI models are not static software versions. Think of them less like an installed application and more like a live, evolving service. Google might push a minor update, deprecate an older version, or replace a model entirely, moving it to a “legacy” status that still shows up in documentation but is no longer accessible via the primary API. This phenomenon, which we can call “model drift,” means that a perfectly functional script from last month can suddenly break today.
If you’re following a tutorial that is even a few weeks old, you run the risk of relying on a model name that has been deprecated, renamed, or simply updated. This script acts as your immediate defense against that frustrating time sink.
Hardcoding vs. Dynamic Discovery
Many developers start a project by hardcoding a familiar model name like model='gemini-2.5-flash'. While this works initially, it introduces significant risk for long-term maintenance. When that model eventually gets superseded (e.g., by gemini-2.5-flash-2025q4), your project breaks without a clear reason why.
The benefit of dynamic discovery is stability. By generating a list of “safe” models right before you start coding, you ensure that the model you choose is verified as live and accessible on the server right now. This simple habit elevates your project from a quick proof-of-concept to a robust, long-term application.
Where Does the Data Come From?
So, how do we get this real-time, authoritative list? We don’t rely on blog posts or outdated GitHub repos. We go straight to the source: the Google AI API endpoint itself.
Inside the Google AI Studio
The google-generativeai SDK includes a function that talks directly to the official catalog endpoint, specifically designed for this purpose: models.list(). This call returns the full inventory of everything Google is serving up, including the internal details of each model’s capabilities and current status. It is the official, real-time catalog of what’s live on the servers.
Filtering the Noise
The raw API response, however, can be a bit overwhelming. It includes models for embeddings, vision-only tasks, models designed for specific file processing, and various legacy options. For a developer focused on text generation or building a chat application, most of that data is just noise.
Our “Where” Logic is simple and powerful: We only want models where the property supported_generation_methods includes generateContent. This immediately filters the hundreds of entries down to the handful of models that can actually handle your text prompts, streamlining your development choices.
Here is the Python script that implements this dynamic discovery process:
import os
import google.generativeai as genai
from dotenv import load_dotenv
# 1. Load the environment variables from .env file
load_dotenv()
# 2. Fetch the specific key you defined
api_key = os.getenv("GOOGLE_AI_API_KEY")
if not api_key:
print("Error: GOOGLE_AI_API_KEY not found in .env file.")
else:
# 3. Configure the Google AI SDK
genai.configure(api_key=api_key)
print("Fetching model list...")
try:
# 4. Open a file to write the results
with open("available_models.txt", "w") as f:
f.write("--- Available Google AI Models (GenerateContent Supported) ---\n\n")
# 5. Loop through available models
for model in genai.list_models():
# Filter: Only show models that support content generation (chat/text)
if 'generateContent' in model.supported_generation_methods:
# Get useful metadata for each model
input_limit = model.input_token_limit
output_limit = model.output_token_limit
line = (
f"Name: {model.name}\n"
f"Description: {model.description}\n"
f"Input Limit: {input_limit} tokens\n"
f"Max Output: {output_limit} tokens\n"
)
print(f"Found: {model.name}") # Print to console so you know it's working
f.write(line + "-" * 40 + "\n")
print("\nSuccess! List saved to 'available_models.txt'")
except Exception as e:
print(f"An error occurred: {e}")
A Walkthrough of the Dynamic Discovery Script
This script is less than 30 lines of code, but it encapsulates multiple best practices in modern API development. It’s an efficient diagnostic tool and a great setup guide all in one.
Secure Authentication
Notice the use of os and dotenv right at the top. This isn’t just for neatness; it’s a core security best practice. By loading your GOOGLE_AI_API_KEY from a separate .env file, you ensure that the sensitive key never ends up committed to a public GitHub repository. This is non-negotiable for any professional project.
The script uses the environment variable to configure the SDK securely, ensuring the subsequent API calls are properly authenticated.
The list_models() Method
The line for model in genai.list_models(): is the engine of the script. This single function call handles the HTTP request, authentication, and JSON parsing, returning an iterable list of structured Model objects.
This is crucial because it retrieves the data directly from the current live environment, effectively guaranteeing the model names you see are accurate at the time you run the script.
Formatting the Output
The original outline mentioned adding useful columns, and that’s precisely what we’ve done by enhancing the script to extract more than just the model name. Each Model object contains attributes like input_token_limit and output_token_limit.
By including these in the output file, you convert a simple list of names into an actionable resource. You can immediately see the context window size and the maximum response length for each available model, helping you make informed decisions before writing a single line of application logic.
When Should You Run This?
This script isn’t just for when things break; it should be part of your standard operating procedure for every AI-powered project. Using it proactively will save you hours of head-scratching down the line.
The “Hello World” of a New Project
We recommend running this script as the absolute first step in setting up any new virtual environment. After installing your dependencies (like google-generativeai and python-dotenv) and setting your API key, run the discovery script.
This confirms two things instantly: your API key is correctly configured, and you have an up-to-date, verified list of models you can actually use. It’s the true “hello world” of a successful AI project setup.
Troubleshooting 404 Errors
If you encounter the dreaded “404 Model Not Found” error in an older project that used to work, don’t immediately dive into your application code. The first diagnostic step should be running this discovery script.
Check your available_models.txt file against the model name in your broken code. More often than not, you’ll find that gemini-1.5-pro has quietly transitioned to gemini-1.5-pro-002, and a single string change is all that’s required to bring your application back to life. It’s a simple, high-leverage diagnostic tool.
Final Thoughts on Model Resilience
In the fast-moving landscape of large language models, model names are ephemeral. They are constantly shifting, being refined, and upgraded in the background. Relying on static tutorials or old documentation is a recipe for frustration and hours spent debugging “ghost” model names that the server simply no longer recognizes.
This simple, self-contained Python script is your ticket to model resilience. It saves you from that infuriating “404” error by giving you a direct, real-time snapshot of the available services. Take a moment right now to save this snippet in your personal code library or Gists. It’s one of the highest-value, lowest-effort habits you can adopt to keep your AI development workflow fast, stable, and sane.