deepseek-ai/deepseek-harness · error

BasicCompactionConfig: duplicate model policy for ${source.p

Error message

BasicCompactionConfig: duplicate model policy for ${source.provider}/${source.model}

What it means

Each modelPolicies entry targets exactly one provider/model route, and resolveTargetPolicy() picks the match with Array.find — a duplicate provider+model pair is ambiguous because only the first entry could ever win. resolveModelPolicies() keys entries by provider/model identity and throws on the second identical pair at plugin load.

Source

Thrown at packages/compaction/compaction-basic/src/config.ts:205

      `${name}: retainRatio (${retention.retainRatio}) must be less than `
      + `the resolved thresholdRatio (${thresholdRatio})`,
    )
  }
}

/** Validate, detach, and reject duplicate exact-target policies. */
function resolveModelPolicies(configured: unknown): ModelCompactPolicyConfig[] {
  if (configured === undefined) return []
  if (!Array.isArray(configured)) {
    throw new Error('BasicCompactionConfig: modelPolicies must be an array')
  }
  const seen = new Set<string>()
  return configured.map((source: unknown, index) => {
    const name = `BasicCompactionConfig: modelPolicies[${index}]`
    assertModelPolicy(source, name)
    const key = `${source.provider}\u0000${source.model}`
    if (seen.has(key)) {
      throw new Error(
        `BasicCompactionConfig: duplicate model policy for ${source.provider}/${source.model}`,
      )
    }
    seen.add(key)
    return { ...source }
  })
}

/** Validate one untrusted exact-target override and narrow its public type. */
function assertModelPolicy(
  source: unknown,
  name: string,
): asserts source is ModelCompactPolicyConfig {
  if (!isUnknownRecord(source)) throw new Error(`${name} must be an object`)
  validateKeys(source, MODEL_POLICY_KEYS, name)
  assertNonEmptyString(`${name}.provider`, source.provider)
  assertNonEmptyString(`${name}.model`, source.model)
  validatePolicy(source, name)

View on GitHub (pinned to b150a551b8)

Solutions

  1. Delete the duplicate and keep exactly one entry per provider/model pair
  2. If the duplicates carried different fields, merge those fields into one entry — unspecified fields inherit from top-level defaults, so one entry can hold everything
  3. When configs are merged or generated, dedupe modelPolicies by provider+model in the merge step before deploy

Example fix

# before — two entries for deepseek/deepseek-chat
modelPolicies:
  - provider: deepseek
    model: deepseek-chat
    maxTokens: 16384
  - provider: deepseek
    model: deepseek-chat
    maxTokens: 32768

# after — one merged entry
modelPolicies:
  - provider: deepseek
    model: deepseek-chat
    maxTokens: 32768
Defensive patterns

Strategy: validation

Validate before calling

const seen = new Set<string>()
for (const [i, p] of (config.modelPolicies ?? []).entries()) {
  const key = `${p.provider} ${p.model}`
  if (seen.has(key)) throw new Error(`modelPolicies[${i}] duplicates ${key}`)
  seen.add(key)
}
resolveConfig(config)

Try / catch

try {
  resolveConfig(config)
} catch (err) {
  const msg = (err as Error).message
  const route = msg.match(/duplicate model policy for (.+)$/)?.[1]
  if (route !== undefined) {
    throw new Error(
      `config has overlapping overrides for ${route}; merge them into one entry`,
      { cause: err },
    )
  }
  throw err
}

Prevention

When it happens

Trigger: Two entries in modelPolicies with the same provider AND model strings (matching is exact). Typical: duplicating an entry to tweak values and forgetting to change model, or concatenating two config files that both tune the same route.

Common situations: Copy-paste of an existing per-model override; merging team or environment configs that append entries instead of replacing; generated configs emitting one entry per tuning knob.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/8f692da360eb3f83. Report an issue: GitHub.