JuliusBrussee/caveman · error
unsupported image token profile
Error message
unsupported image token profile
What it means
While building Gemini inline image parts, the renderer calls engineimage.EstimateTokensForModel("gemini", model, mediaResolution, w, h) per image to cost the request. If that (model, mediaResolution) combination has no token-estimation profile, estimation returns supported=false and rendering aborts: the pipeline refuses to emit images whose cost it cannot account for.
Source
Thrown at engine/pixel/transform_gemini.go:1004
imgs, err = RenderTextToPNGsMultiCol(text, effectiveCols, effectiveNumCols)
} else if style == (RenderStyle{}) {
imgs, err = RenderTextToPNGs(text, effectiveCols, RenderStyle{})
} else {
imgs, err = RenderTextToPNGsWithCharLimit(text, effectiveCols, maxCharsPerImage, style, MaxHeightPx, "")
}
if err != nil {
return geminiRenderResult{}, err
}
res := geminiRenderResult{droppedCodepoints: make(map[rune]int)}
for _, img := range imgs {
b64 := base64.StdEncoding.EncodeToString(img.PNG)
res.parts = append(res.parts, geminiPart{InlineData: &geminiInlineData{MimeType: "image/png", Data: b64}})
res.imageCount++
res.imageBytes += len(img.PNG)
res.imagePixels += img.Width * img.Height
tokens, supported := engineimage.EstimateTokensForModel("gemini", model, mediaResolution, img.Width, img.Height)
if !supported {
return geminiRenderResult{}, errors.New("unsupported image token profile")
}
res.imageTokens += int(math.Ceil(float64(tokens) * ImageCostSafetyMargin))
res.droppedChars += img.DroppedChars
for cp, n := range img.DroppedCodepoints {
res.droppedCodepoints[cp] += n
}
}
return res, nil
}
func evalGeminiProfitability(model, mediaResolution, text string, cols, imageCountCap, numCols int, charsPerToken, priorWarmTokens, priorWarmImageTokens float64, shrinkWidth bool, maxCharsPerImage int, dense bool) *geminiGateEval {
if text == "" {
return nil
}
cpt := charsPerToken
if !isFinitePositive(cpt) {
cpt = CharsPerToken
}View on GitHub (pinned to 27d5a3981a)
Solutions
- Check the model id spelling against the estimator's supported list (engineimage package)
- Use a known mediaResolution value for that model
- If the model is genuinely new, add its token profile to engineimage or fall back to text-only rendering for unsupported models
Example fix
// before
res, err := renderGeminiInlineDataParts("gemini-9-ultra", "media_hi", text, ...) // unknown model
// after
// use a model id the estimator supports, or gate image rendering:
if !engineimage.ModelSupported("gemini", model, mediaResolution) {
// render text-only path
}
res, err := renderGeminiInlineDataParts(model, mediaResolution, text, ...) Defensive patterns
Strategy: validation
Validate before calling
// verify the (model, mediaResolution) pair is estimable before rendering with images
if _, ok := engineimage.EstimateTokensForModel("gemini", model, mediaResolution, 1, 1); !ok {
// use a supported model/resolution or the text-only path
} Type guard
func imageProfileSupported(model, res string) bool {
_, ok := engineimage.EstimateTokensForModel("gemini", model, res, 1, 1)
return ok
} Try / catch
res, err := renderGeminiInlineDataParts(model, res0, ...)
if err != nil && strings.Contains(err.Error(), "unsupported image token profile") {
// fall back to text-only rendering
} Prevention
- Pin model ids to ones the estimator table knows
- Re-check supported profiles when upgrading the engine or models
- Validate mediaResolution against the documented enum
When it happens
Trigger: Passing a model string the estimator does not recognize (new, renamed, or misspelled Gemini model id), or a mediaResolution value outside the known set, together with a render that actually produces at least one image.
Common situations: Upgrading to a newly released Gemini model before the estimator table knows it; typo'd model name from config; passing an empty model that falls back to an unrecognized default; unusual media_resolution enum values from client config.
Related errors
- empty render text
- body must be a JSON object
- gemini bearer credential requires a valid x-goog-user-projec
- existing Gemini Caveman routing block is corrupted; run `cav
- managed Gemini CLI routing is unsupported because Gemini CLI
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/86f9136e90a14f8b.
Report an issue: GitHub.