Skip to content

[BUG] Bedrock Claude application inference profile reasoning variants send invalid payload #31749

Closed as not planned

Description

@jpastuszuk

Description

Summary

Amazon Bedrock Claude models invoked through an application-inference-profile ARN work normally in OpenCode, but reasoning effort variants are broken.

When the custom model is marked as reasoning: true, OpenCode exposes/allows reasoning variants such as high. Selecting a variant causes Bedrock to reject the request because OpenCode sends an invalid reasoning payload for Claude application inference profiles.

This looks related to #10611, but that issue is closed after a fixed-budget workaround. The workaround can enable default thinking, but it does not fix the effort selector / --variant behavior.

Background

AWS Bedrock supports using application inference profile ARNs as modelId. In OpenCode, the model config looks like this:

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "amazon-bedrock": {
      "options": {
        "region": "us-east-2",
        "profile": "REDACTED"
      },
      "models": {
        "anthropic.claude-sonnet-4-6": {
          "name": "Claude Sonnet 4.6",
          "id": "arn:aws:bedrock:us-east-2:ACCOUNT_ID:application-inference-profile/PROFILE_ID"
        }
      }
    }
  }
}

Without reasoning variants, the model works:

opencode run "Return exactly: ok" \
  --model "amazon-bedrock/anthropic.claude-sonnet-4-6" \
  --format json

It returns the expected text response.

Reproduction

Add reasoning: true to the custom model:

{
  "name": "Claude Sonnet 4.6",
  "id": "arn:aws:bedrock:us-east-2:ACCOUNT_ID:application-inference-profile/PROFILE_ID",
  "reasoning": true
}

Run with a reasoning variant:

opencode run "Return exactly: ok" \
  --model "amazon-bedrock/anthropic.claude-sonnet-4-6" \
  --variant high \
  --format json

Actual result:

{
  "type": "error",
  "error": {
    "name": "APIError",
    "data": {
      "message": "undefined: The model returned the following errors: reasoningConfig: Extra inputs are not permitted",
      "statusCode": 400,
      "responseBody": "{\"message\":\"The model returned the following errors: reasoningConfig: Extra inputs are not permitted\"}"
    }
  }
}

Workaround tested

The workaround from #10611 was tested:

{
  "name": "Claude Sonnet 4.6",
  "id": "arn:aws:bedrock:us-east-2:ACCOUNT_ID:application-inference-profile/PROFILE_ID",
  "reasoning": true,
  "options": {
    "reasoningConfig": {},
    "additionalModelRequestFields": {
      "reasoning_config": {
        "type": "enabled",
        "budget_tokens": 8192
      }
    }
  }
}

This does enable fixed/default reasoning. Running with --thinking on a reasoning-style prompt produces a reasoning part with Bedrock metadata/signature.

However, the selector/variant path is still broken. Running the same model with --variant high still fails with:

reasoningConfig: Extra inputs are not permitted

Expected behavior

For Claude models configured through Bedrock application inference profile ARNs, OpenCode should either:

  • detect the underlying model family from the OpenCode model key/name, not only from the ARN in model.api.id, and generate Claude-compatible Bedrock reasoning variants, or
  • provide a documented way to set the base/source model family for custom Bedrock profile models, or
  • avoid exposing reasoning variants that send invalid payloads.

Suspected cause

For application inference profiles, model.api.id is an ARN:

arn:aws:bedrock:us-east-2:ACCOUNT_ID:application-inference-profile/PROFILE_ID

That ARN does not contain anthropic or claude. The Bedrock variant logic appears to use model.api.id to decide which reasoning payload to send, so Claude profiles can fall through to the wrong Bedrock reasoning path.

This is similar to the custom inference profile detection issue fixed for caching in #9803 / #9838, where model.id also had to be checked. A similar check may be needed in ProviderTransform.variants, or custom Bedrock models may need an explicit sourceModelId / family field.

Related issues / PRs

Plugins

None

OpenCode version

1.16.2

Steps to reproduce

  1. Configure an Amazon Bedrock custom model whose id is a Claude application inference profile ARN.

  2. Add reasoning: true to that custom model.

  3. Run:

    opencode run "Return exactly: ok" \
      --model "amazon-bedrock/anthropic.claude-sonnet-4-6" \
      --variant high \
      --format json
  4. Observe the Bedrock 400 error:

    reasoningConfig: Extra inputs are not permitted
    
  5. Add the workaround from AWS Bedrock Claude models with Inference Profile ARNs fail to trigger Extended Thinking (Reasoning) #10611 using additionalModelRequestFields.reasoning_config.

  6. Confirm --thinking can produce reasoning output with a fixed budget.

  7. Run again with --variant high and observe the same Bedrock 400 error.

Screenshot and/or share link

N/A. CLI JSON error and config snippets are included above.

Operating System

macOS

Terminal

Terminal.app

Activity

  1. rekram1-node commented on Jun 10, 2026

    @rekram1-node
    Contributor

    share opencode debug config

    eveyrthing should work out of the box, your config is prolly breaking things

  2. jpastuszuk commented on Jun 11, 2026

    @jpastuszuk
    Author

    Here is the redacted opencode debug config block:

    {
      "$schema": "https://opencode.ai/config.json",
      "disabled_providers": [
        "opencode"
      ],
      "model": "openai/gpt-5.5",
      "small_model": "openai/gpt-5.5-fast",
      "provider": {
        "amazon-bedrock": {
          "whitelist": [
            "anthropic.claude-opus-4-8",
            "anthropic.claude-opus-4-7",
            "anthropic.claude-sonnet-4-6",
            "anthropic.claude-haiku-4-5-20251001-v1:0",
            "anthropic.claude-opus-4-6-v1"
          ],
          "options": {
            "region": "us-east-2",
            "profile": "claude-code-bedrock"
          },
          "models": {
            "anthropic.claude-opus-4-8": {
              "name": "Claude Opus 4.8",
              "id": "arn:aws:bedrock:us-east-2:[ACCOUNT_ID]:application-inference-profile/[PROFILE_ID]"
            },
            "anthropic.claude-opus-4-7": {
              "name": "Claude Opus 4.7",
              "id": "arn:aws:bedrock:us-east-2:[ACCOUNT_ID]:application-inference-profile/[PROFILE_ID]"
            },
            "anthropic.claude-sonnet-4-6": {
              "name": "Claude Sonnet 4.6",
              "id": "arn:aws:bedrock:us-east-2:[ACCOUNT_ID]:application-inference-profile/[PROFILE_ID]",
              "reasoning": true,
              "options": {
                "reasoningConfig": {},
                "additionalModelRequestFields": {
                  "reasoning_config": {
                    "type": "enabled",
                    "budget_tokens": 8192
                  }
                }
              }
            },
            "anthropic.claude-haiku-4-5-20251001-v1:0": {
              "name": "Claude Haiku 4.5",
              "id": "arn:aws:bedrock:us-east-2:[ACCOUNT_ID]:application-inference-profile/[PROFILE_ID]"
            },
            "anthropic.claude-opus-4-6-v1": {
              "name": "Claude Opus 4.6",
              "id": "arn:aws:bedrock:us-east-2:[ACCOUNT_ID]:application-inference-profile/[PROFILE_ID]"
            }
          }
        }
      },
      "lsp": {
        "typescript": {
          "command": [
            "typescript-language-server",
            "--stdio"
          ],
          "extensions": [
            ".ts",
            ".tsx",
            ".js",
            ".jsx",
            ".mjs",
            ".cjs",
            ".mts",
            ".cts"
          ]
        },
        "pyright": {
          "command": [
            "pyright-langserver",
            "--stdio"
          ],
          "extensions": [
            ".py",
            ".pyi"
          ]
        },
        "terraform": {
          "command": [
            "terraform-ls",
            "serve"
          ],
          "extensions": [
            ".tf",
            ".tfvars"
          ]
        }
      },
      "agent": {
        "build": {
          "permission": {
            "read": "allow",
            "glob": "allow",
            "grep": "allow",
            "list": "allow",
            "external_directory": {
              "*": "ask",
              "/tmp/**": "allow",
              "/private/tmp/**": "allow"
            },
            "bash": {
              "*": "allow",
              "git *": "ask",
              "git reset*": "ask",
              "git clean*": "ask",
              "git branch -D*": "ask",
              "git branch -d*": "ask",
              "git push*": "ask",
              "git commit*": "ask",
              "git restore*": "ask",
              "git status*": "allow",
              "git diff*": "allow",
              "git fetch*": "allow",
              "git log*": "allow",
              "git rev-list*": "allow",
              "git ls-remote*": "allow",
              "git show*": "allow",
              "git blame*": "allow",
              "git ls-files*": "allow",
              "git rev-parse*": "allow",
              "git remote -v*": "allow",
              "git remote show*": "allow",
              "git merge-base*": "allow",
              "git branch --show-current*": "allow",
              "git branch --list*": "allow",
              "git tag --list*": "allow",
              "git tag -l*": "allow",
              "git describe*": "allow",
              "git reflog*": "allow",
              "git stash list*": "allow",
              "git stash show*": "allow",
              "git worktree list*": "allow",
              "git submodule status*": "allow",
              "git config --get*": "allow",
              "git config --list*": "allow",
              "git switch*": "allow",
              "git checkout*": "ask",
              "git pull*": "allow",
              "git merge*": "ask",
              "git rebase*": "ask",
              "terraform *": "ask",
              "terraform version*": "allow",
              "terraform validate*": "allow",
              "terraform fmt": "allow",
              "terraform fmt *": "allow",
              "terraform fmt -recursive": "allow",
              "terraform fmt -check*": "allow",
              "terraform -chdir=* validate*": "allow",
              "terraform show*": "allow",
              "terraform output*": "allow",
              "terraform providers*": "allow",
              "terraform graph*": "allow",
              "terraform state list*": "allow",
              "terraform state show*": "allow",
              "terraform workspace list*": "allow",
              "terraform workspace show*": "allow"
            }
          },
          "options": {}
        }
      }
    }

    The Sonnet config includes the workaround from #10611. Fixed-budget thinking works with --thinking, but the effort selector path still fails.

    Command:

    opencode run "Return exactly: ok" \
      --model "amazon-bedrock/anthropic.claude-sonnet-4-6" \
      --variant high \
      --format json

    Error:

    reasoningConfig: Extra inputs are not permitted
    

    So from what I can see, fixed-budget Bedrock thinking works, but reasoning variants still generate an invalid Bedrock payload when the model id is an application-inference-profile ARN.

  3. jpastuszuk commented on Jul 14, 2026

    @jpastuszuk
    Author

    Update: I have an operational workaround for this, but the underlying issue is still reproducible and this should not be considered the target fix.

    What I verified

    I reproduced the automatic variant failure on:

    • OpenCode 1.17.15
    • the current release, v1.17.20
    • current dev at de14bb2e0

    The application inference profile itself is valid: the same profile works without a variant, and direct Bedrock requests using Claude's native adaptive-thinking fields work. This rules out a broken profile or AWS permissions as the cause.

    For --variant high, the generated request eventually contains the equivalent of:

    {
      "additionalModelRequestFields": {
        "reasoningConfig": {
          "type": "enabled",
          "maxReasoningEffort": "high"
        }
      }
    }

    Claude rejects that field with:

    reasoningConfig: Extra inputs are not permitted
    

    Root cause/context

    There are two model identities involved here:

    • the OpenCode model key, e.g. anthropic.claude-sonnet-4-6, which identifies the model family;
    • the Bedrock invocation ID, which is an opaque application-inference-profile ARN and does not contain anthropic or claude.

    OpenCode's Bedrock variant selection uses the invocation/API ID for family detection. Because the ARN does not contain anthropic, the request falls through to the non-Claude Bedrock reasoning format.

    There is also a second detection layer in @ai-sdk/amazon-bedrock (4.0.112 in the tested OpenCode versions). It likewise derives behavior from the ARN passed as the model ID. Therefore, changing only the OpenCode family check is not sufficient if the SDK still sees an opaque ARN and serializes the reasoning settings incorrectly. This is the same general class of upstream problem described in vercel/ai#11035.

    One other potentially confusing detail: --thinking controls whether reasoning parts are displayed. It does not, by itself, enable the correct Bedrock reasoning request. That is why the fixed-budget workaround from #10611 can appear to solve thinking while --variant high continues to fail.

    Copy/paste configuration workaround

    The workaround is to disable OpenCode's automatically generated reasoning variants for each affected custom model and define explicit variants that send the model's native Bedrock fields directly.

    The following is the complete models block I am currently using. Replace each ARN placeholder with its corresponding application inference profile ARN and merge the block under provider.amazon-bedrock.models in opencode.json.

    Full models configuration
    {
      "anthropic.claude-opus-4-8": {
        "name": "Claude Opus 4.8",
        "id": "<OPUS_4_8_APPLICATION_INFERENCE_PROFILE_ARN>",
        "reasoning": false,
        "variants": {
          "low": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "low" }
            }
          },
          "medium": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "medium" }
            }
          },
          "high": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "high" }
            }
          },
          "max": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "max" }
            }
          }
        }
      },
      "anthropic.claude-opus-4-7": {
        "name": "Claude Opus 4.7",
        "id": "<OPUS_4_7_APPLICATION_INFERENCE_PROFILE_ARN>",
        "reasoning": false,
        "variants": {
          "low": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "low" }
            }
          },
          "medium": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "medium" }
            }
          },
          "high": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "high" }
            }
          },
          "max": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive", "display": "summarized" },
              "output_config": { "effort": "max" }
            }
          }
        }
      },
      "anthropic.claude-sonnet-4-6": {
        "name": "Claude Sonnet 4.6",
        "id": "<SONNET_4_6_APPLICATION_INFERENCE_PROFILE_ARN>",
        "reasoning": false,
        "variants": {
          "low": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive" },
              "output_config": { "effort": "low" }
            }
          },
          "medium": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive" },
              "output_config": { "effort": "medium" }
            }
          },
          "high": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive" },
              "output_config": { "effort": "high" }
            }
          },
          "max": {
            "additionalModelRequestFields": {
              "thinking": { "type": "adaptive" },
              "output_config": { "effort": "max" }
            }
          }
        }
      },
      "anthropic.claude-haiku-4-5-20251001-v1:0": {
        "name": "Claude Haiku 4.5",
        "id": "<HAIKU_4_5_APPLICATION_INFERENCE_PROFILE_ARN>",
        "reasoning": false,
        "variants": {
          "low": {
            "additionalModelRequestFields": {
              "thinking": { "type": "enabled", "budget_tokens": 1024 }
            }
          },
          "medium": {
            "additionalModelRequestFields": {
              "thinking": { "type": "enabled", "budget_tokens": 4096 }
            }
          },
          "high": {
            "additionalModelRequestFields": {
              "thinking": { "type": "enabled", "budget_tokens": 8192 }
            }
          },
          "max": {
            "additionalModelRequestFields": {
              "thinking": { "type": "enabled", "budget_tokens": 16384 }
            }
          }
        }
      },
      "anthropic.claude-opus-4-6-v1": {
        "name": "Claude Opus 4.6",
        "id": "<OPUS_4_6_APPLICATION_INFERENCE_PROFILE_ARN>"
      }
    }

    The previous options.reasoningConfig / additionalModelRequestFields.reasoning_config fixed-budget workaround must be removed from these model definitions so that it does not conflict with the explicit variants. Restart OpenCode after changing the config because it is loaded at startup.

    I tested all four explicit Sonnet variants (low, medium, high, and max) on an otherwise unmodified OpenCode 1.17.15; all completed successfully and returned Claude reasoning content where appropriate.

    The adaptive request shape was also accepted in direct tests for Opus 4.7/4.8 application profiles. display: "summarized" asks those models to return summarized reasoning. Haiku 4.5 is different: it rejected output_config.effort, but accepted fixed thinking budgets, which is why its four UI variants map to budget_tokens values instead.

    The Opus 4.6 entry is intentionally left without reasoning variants. The application profile tested for that model returned The provided model identifier is invalid even without reasoning, so I could not validate its reasoning capabilities independently from the profile problem. It is included only to show the complete model block; remove it if there is no valid Opus 4.6 profile in the target account.

    This difference between adaptive Opus/Sonnet behavior and fixed-budget Haiku behavior further suggests that model-family/capability metadata needs to be preserved separately from the transport ARN rather than inferred from the ARN string.

    Why this is not the target fix

    This workaround hardcodes provider-specific behavior in every user's config, bypasses OpenCode's normal reasoning: true flow, and must be maintained per model capability. The original automatic variant path still sends an invalid payload.

    A proper fix should preserve a semantic/source model identity independently from the Bedrock invocation ARN (for example, sourceModelId/family/capability metadata), and then ensure that either OpenCode or the Bedrock SDK emits Claude-native thinking + output_config fields for application inference profiles. Until that is implemented, explicit custom variants are only an operational workaround.

  4. github-actions commented on Sep 13, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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