[PR #10387] fix(provider): use deep merge for providerOptions in applyCaching - Issue #10241 #13429

Closed
opened 2026-02-16 18:18:17 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/10387

State: closed
Merged: No


Problem

transform.applyCaching overrides previous providerOptions set by earlier transforms (e.g., normalizeMessages).

Example: OpenAI-compatible provider with Claude model uses interleaving (set in normalizeMessages), but applyCaching overwrites these options, losing the interleaving configuration.

Root Cause

The spread operator ({...a, ...b}) was used to merge provider options, which overwrites properties instead of deep merging them:

typescript // Before (WRONG): lastContent.providerOptions = { n ...lastContent.providerOptions, // Gets overwritten! n ...providerOptions, }

Solution

Changed from shallow spread to mergeDeep() from remeda:

``typescript
// After (CORRECT):
import { mergeDeep, unique } from "remeda"

lastContent.providerOptions = mergeDeep(
n lastContent.providerOptions ?? {},
n providerOptions[providerID] ?? providerOptions.anthropic
)
``

Impact

  • Preserves interleaving options from normalizeMessages
  • Deeply merges all nested provider options
  • Compatible with all providers (anthropic, openrouter, bedrock, openaiCompatible)

Technical Details

  • File: packages/opencode/src/provider/transform.ts
  • Function: applyCaching()
  • Changed 2 locations where provider options are merged
  • Added type assertion for providerID key access

Fixes #10241 - Critical bug affecting provider option composition

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/10387 **State:** closed **Merged:** No --- ## Problem `transform.applyCaching` overrides previous `providerOptions` set by earlier transforms (e.g., `normalizeMessages`). **Example**: OpenAI-compatible provider with Claude model uses interleaving (set in `normalizeMessages`), but `applyCaching` overwrites these options, losing the interleaving configuration. ## Root Cause The spread operator (`{...a, ...b}`) was used to merge provider options, which **overwrites** properties instead of **deep merging** them: ``typescript // Before (WRONG): lastContent.providerOptions = { n ...lastContent.providerOptions, // Gets overwritten! n ...providerOptions, } `` ## Solution Changed from shallow spread to `mergeDeep()` from `remeda`: ``typescript // After (CORRECT): import { mergeDeep, unique } from "remeda" lastContent.providerOptions = mergeDeep( n lastContent.providerOptions ?? {}, n providerOptions[providerID] ?? providerOptions.anthropic ) `` ## Impact - **Preserves interleaving options** from `normalizeMessages` - **Deeply merges** all nested provider options - **Compatible with all providers** (anthropic, openrouter, bedrock, openaiCompatible) ## Technical Details - File: `packages/opencode/src/provider/transform.ts` - Function: `applyCaching()` - Changed 2 locations where provider options are merged - Added type assertion for providerID key access Fixes #10241 - Critical bug affecting provider option composition
yindo added the pull-request label 2026-02-16 18:18:17 -05:00
yindo closed this issue 2026-02-16 18:18:17 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13429