OpenClaw's Gemini CLI Vision Fix Is a Small Shim With a Big Interop Lesson

OpenClaw's Gemini CLI Vision Fix Is a Small Shim With a Big Interop Lesson

OpenClaw's Gemini CLI Vision Fix Is a Small Shim With a Big Interop Lesson

The bug report in GitHub issue #91739 is 11 lines long and contains more diagnostic precision than most support tickets ten times its length. The reporter describes an environment, a model request, a failure mode, a root-cause hypothesis, a local validation of that hypothesis, and a suggested upstream fix. This is how bug reports should look when the reporter understands the system they are filing against.

The failure: OpenClaw's Gateway was rejecting image attachments for google-gemini-cli routes before the Gemini CLI ever had a chance to process them. The model could accept images when called directly through Gemini CLI using the @<workspace-image-path> file reference syntax, and the same Gemini model worked through the PAYG google-aistudio backend. But OpenClaw's capability gate lacked a Gemini CLI image shim, so the platform rejected the attachment at the Gateway layer with UnsupportedAttachmentError: attachment image.png: active model does not accept image inputs — even though the backend could handle it.

Capability Gates Live and Die by Metadata

OpenClaw's Gateway is doing the safe thing in principle: reject unsupported attachments before sending them into a backend that may fail confusingly. That is good architecture. But the safety gate is only as accurate as the capability model behind it. In this case, the backend could handle images through Gemini CLI's file reference path, while OpenClaw's catalog said text-only. The platform protected the user from a failure that would not have happened.

The root cause: resolveGatewayModelSupportsImages had hardcoded image-capability shims for microsoft-foundry GPT and OpenAI models, and for claude-cli Claude models. It had no equivalent google-gemini-cli shim. When the model catalog had a stale or missing entry for a Gemini CLI route, the capability gate fell back to the catalog's conservative default — no image support — even though the actual backend supported it.

PR #91790 adds the missing shim. It recognizes Gemini-family full model IDs (gemini-*) and registered CLI aliases (pro, flash, flash-lite) in both the with-catalog-entry and missing-catalog-entry paths. The fix is narrow: it does not change other CLI providers, non-Gemini Google models, or the model catalog itself. The shim is a runtime safety net for a specific known-compatible family.

Local and CLI-Backed Providers Break Static Catalogs

This bug is a symptom of a broader interop problem that every multi-provider agent stack encounters. CLI providers are weird by design: auth state, version, aliases, and file-prestage semantics live outside the cloud API catalog. A static catalog entry can be accurate for the cloud API and wrong for the CLI backend running on the same machine. Conversely, a CLI provider can support capabilities — like Gemini CLI's @ file references — that the catalog has no way to represent.

The lesson is not "catalogs are bad." It is that capability routing for CLI-backed providers needs runtime shims, not just static metadata. A stale input: ["text"] catalog row should not permanently disable a working image path if the provider family is known to support vision. Conversely, shims must be bounded tightly, or they become optimistic lies that let the platform claim capability it does not have.

PR #91790 gets that balance mostly right: provider-specific, Gemini-family-specific, alias-specific, with tests for both stale and missing catalog rows. The tests cover 18 assertions across gateway-core, gateway-server, and gateway-client shards, which is the right density for a narrow fix with real interop stakes.

What Operators Should Test

If you are running OpenClaw with Gemini CLI as a backend, or mixing PAYG and CLI-backed routes, test image and file attachments through every route you expect to use. Do not assume that because one route handles images, all routes to the same model family will. The capability gate makes per-route decisions based on catalog entries and provider shims, and those can diverge from actual backend capability.

For engineers building multi-provider agent stacks, the action item is to treat capability routing as a first-class concern, not a configuration detail. Send an image. Send a file. Send a tool call. Confirm the route you think you are using is the route that actually runs. Agent orchestration breaks at the seams between catalog metadata, gateway validation, provider adapters, and CLI behavior — exactly where dashboards tend to look green while the actual behavior is more complicated.

The broader lesson: model routing is capability routing. If your agent platform cannot accurately answer "can this exact backend, through this exact route, handle this exact input?", it will either drop useful work or send dangerous work to the wrong place. Both are bugs. The Gemini CLI image shim is a small fix, but it points at a large and ongoing challenge: making multi-provider agent routing as reliable as single-provider routing feels.

Sources: GitHub issue #91739, GitHub PR #91790