can1357/oh-my-pi · error
Thinking effort ${effort} is not supported by ${model.provid
Error message
Thinking effort ${effort} is not supported by ${model.provider}/${model.id}. Supported efforts: ${levels.join(", ")} What it means
The model supports thinking, but the requested Effort is not among the levels the model accepts (getSupportedEfforts from the catalog/KDL rules). requireSupportedEffort throws with the list of supported efforts so the caller can pick a valid one.
Source
Thrown at packages/catalog/src/model-thinking.ts:73
let clamped: Effort | undefined;
for (const effort of levels) {
if (THINKING_EFFORTS.indexOf(effort) > requestedIndex) {
break;
}
clamped = effort;
}
return clamped ?? levels[0];
}
export function requireSupportedEffort<TApi extends Api>(model: ApiModel<TApi>, effort: Effort): Effort {
if (!model.reasoning) {
throw new Error(`Model ${model.provider}/${model.id} does not support thinking`);
}
const levels = getSupportedEfforts(model);
if (!levels.includes(effort)) {
throw new Error(
`Thinking effort ${effort} is not supported by ${model.provider}/${model.id}. Supported efforts: ${levels.join(", ")}`,
);
}
return effort;
}
/** Maps a normalized thinking effort to Google's `thinkingLevel` enum values.
* When a collapsed family routes `minimal` onto the same wire id as `low`
* (Antigravity Gemini 3.6/3.7 Flash), emit `LOW` — Cloud Code Assist rejects
* `MINIMAL` on those `-low` SKUs.
*/
export function mapEffortToGoogleThinkingLevel<TApi extends Api>(
effort: Effort,
model?: ApiModel<TApi>,
): "MINIMAL" | "LOW" | "MEDIUM" | "HIGH" {
if (effort === Effort.Minimal) {
const routing = model?.thinking?.effortRouting;
if (routing?.[Effort.Minimal] && routing[Effort.Minimal] === routing[Effort.Low]) {View on GitHub (pinned to 9690622007)
Solutions
- Use one of the efforts listed in the error message
- Clamp with the level()/supported() helpers which select from getSupportedEfforts
- Update the thinking config for this model in your settings
- If the ladder is wrong, fix it in the KDL compat rules and run `bun run gen:compat`
Example fix
// before
ctx.thinking = { effort: "minimal" }; // model only supports low|medium|high
// after
const effort = thinkingLevel(model) ?? "medium"; // picks a supported level
ctx.thinking = { effort }; Defensive patterns
Strategy: validation
Validate before calling
import { supported } from "@oh-my-pi/pi-catalog/model-thinking";
const allowed = supported(model);
if (!allowed.includes(desiredEffort)) {
desiredEffort = allowed[allowed.length - 1]; // clamp to max supported
}
Type guard
function isSupportedEffort(model: ApiModel<Api>, effort: Effort): boolean {
return supported(model).includes(effort);
} Try / catch
try {
ctx.thinking = { effort };
} catch (err) {
if (err instanceof Error && err.message.includes("Supported efforts:")) {
const levels = err.message.split("Supported efforts: ")[1]?.split(", ") ?? [];
ctx.thinking = { effort: (levels.at(-1) as Effort) ?? undefined };
} else throw err;
} Prevention
- Always derive efforts from supported(model) rather than literals
- Clamp user-supplied effort settings against the model's ladder
- Regenerate compat rules (bun run gen:compat) after KDL edits so ladders stay accurate
When it happens
Trigger: Passing e.g. effort 'high' to a model that only supports ['low','medium'], or 'minimal' on models that predate that level, via effort()/level()/mapped()/getGoogleBudget().
Common situations: Config written for one model copied to another; catalog updated and effort ladder changed; OpenAI 'minimal' effort used against Anthropic-style models.
Related errors
- Model ${model.provider}/${model.id} does not support thinkin
- Received thinking_delta for non-thinking content
- Received thinking_end for non-thinking content
- Anthropic thinking budget requires max_tokens greater than $
- Model ${spec.provider}/${spec.id} resolved to an empty think
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/33534d343eb7e17c.
Report an issue: GitHub.