deepseek-ai/deepseek-harness · error

: unknown key

Error message

${name}: unknown key "${key}"

What it means

Configuration uses strict unknown-key rejection: validateKeys() throws on the first key outside the allowed set, before defaults can hide the mistake. Top level accepts thresholdRatio, retainRatio, retainTokens, summarizationProvider, summarizationModel, maxTokens, compactionRetries, maxOverflowRetries, modelPolicies, and auto; a modelPolicies entry accepts provider and model plus the eight policy fields (not auto).

Solutions

  1. Fix the rejected key named in the message against the allowed set for that scope (e.g. maxToken to maxTokens)
  2. Move scope-bound keys to the correct block: auto and modelPolicies are top-level; provider and model belong to entries
  3. Delete keys the current version does not support instead of leaving them in place

Example fix

# before
modelPolicies:
  - provider: deepseek
    model: deepseek-chat
    maxToken: 16384   # typo: unknown key
    auto: false       # wrong scope: top-level only

# after
auto: false
modelPolicies:
  - provider: deepseek
    model: deepseek-chat
    maxTokens: 16384
Defensive patterns

Strategy: validation

Validate before calling

const POLICY_KEYS = new Set([
  'thresholdRatio', 'retainRatio', 'retainTokens',
  'summarizationProvider', 'summarizationModel',
  'maxTokens', 'compactionRetries', 'maxOverflowRetries',
])
const TOP_KEYS = new Set([...POLICY_KEYS, 'modelPolicies', 'auto'])
const ENTRY_KEYS = new Set([...POLICY_KEYS, 'provider', 'model'])

function checkKeys(obj: object, allowed: Set<string>, where: string) {
  for (const k of Object.keys(obj)) {
    if (!allowed.has(k)) throw new Error(`${where}: unknown key ${k}`)
  }
}

checkKeys(config, TOP_KEYS, 'config')
for (const [i, e] of (config.modelPolicies ?? []).entries()) {
  checkKeys(e, ENTRY_KEYS, `modelPolicies[${i}]`)
}

Try / catch

try {
  resolveConfig(config)
} catch (err) {
  const key = (err as Error).message.match(/unknown key "(.+?)"/)?.[1]
  if (key !== undefined) {
    throw new Error(
      `config key ${key} is misspelled, stale, or in the wrong scope — compare with the allowed key set`,
      { cause: err },
    )
  }
  throw err
}

Prevention

When it happens

Trigger: A misspelled key (retainToken, thresoldRatio, summarisationModel), a stale key from another version, or a key nested in the wrong scope: 'auto' inside a modelPolicies entry, or 'modelPolicies' nested inside an entry.

Common situations: Version upgrades that renamed keys; copy-paste between different plugins' config blocks; editor autocompletion inserting a plausible-but-wrong field name.

Related errors


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

Appendix: source

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

    throw new Error(`${name}.summarizationProvider must be a string`)
  }
  if (model !== undefined && typeof model !== 'string') {
    throw new Error(`${name}.summarizationModel must be a string`)
  }
  if (provider === undefined && model === undefined) return
  if (provider === undefined || model === undefined
    || (provider.length === 0) !== (model.length === 0)) {
    throw new Error(
      `${name}: summarizationProvider and summarizationModel must be set together `
      + 'as an empty or non-empty pair',
    )
  }
}

/** Reject stale or misspelled keys before defaults can hide them. */
function validateKeys(config: object, keys: ReadonlySet<string>, name: string): void {
  for (const key of Object.keys(config)) {
    if (!keys.has(key)) throw new Error(`${name}: unknown key "${key}"`)
  }
}

function isUnknownRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value)
}

function assertNonEmptyString(name: string, value: unknown): asserts value is string {
  if (typeof value !== 'string' || value.length === 0) {
    throw new Error(`${name} must be a non-empty string`)
  }
}

function assertPositiveInteger(name: string, value: unknown): asserts value is number {
  if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {
    throw new Error(`${name} (${String(value)}) must be a positive integer`)
  }
}

View on GitHub (pinned to b150a551b8)