Skip to content

[Bug]: Reasoning effort sent to models that do not support it #2940

@tivris

Description

@tivris

Bug Description

Setting reasoning.enabled = false and effort = "none" in .forge.toml does not prevent the effort parameter from being sent to the Anthropic API. Models that do not support output_config.effort (e.g. Claude Haiku 4.5) reject the request with a 400.

Reported in #2924 by @pcastellazzi.

Root Cause

Two interacting bugs:

  1. Config merge direction (crates/forge_app/src/agent.rs:164-167): The merge uses overwrite_none with the agent as base, so the forge agent's reasoning.enabled: true (hardcoded in forge.md:5-6) silently overrides the user's enabled: false. The user config can never turn off reasoning through .forge.toml.

  2. Effort::None semantics (crates/forge_app/src/dto/anthropic/request.rs:153): Effort::None is documented as "No reasoning; skips the thinking step entirely" but the Anthropic DTO maps it to OutputEffort::Low, which enables low-effort reasoning. The OpenAI path already handles this correctly (maps to "none").

Fix

  1. Reverse the merge direction so user config takes priority (matching the compact config pattern already used in the same file).
  2. When Effort::None reaches the Anthropic DTO, return (None, None) instead of OutputEffort::Low.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions