deepseek-ai/deepseek-harness · error
${name}.summarizationModel must be a string
Error message
${name}.summarizationModel must be a string What it means
summarizationModel names the model that performs compaction summarization. validateSummarizationPair() requires a string when the key is present; numbers, booleans, arrays, objects, and null all fail. It participates in the same pair rule as summarizationProvider.
Source
Thrown at packages/compaction/compaction-basic/src/config.ts:265
if (maxOverflowRetries !== undefined) {
assertNonNegativeInteger(`${name}.maxOverflowRetries`, maxOverflowRetries)
}
validateSummarizationPair(config, name)
}
/** Require one scope to omit, clear, or replace the summarization target as a pair. */
function validateSummarizationPair(
config: CompactionPolicyConfig | Record<string, unknown>,
name: string,
): void {
const provider = config.summarizationProvider
const model = config.summarizationModel
if (provider !== undefined && typeof provider !== 'string') {
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}"`)
}
}
View on GitHub (pinned to b150a551b8)
Solutions
- Set it to exactly one non-empty model string alongside summarizationProvider
- Remove both keys to inherit the effective setting
- If you need a different summarization model per route, put the pair in that route's modelPolicies entry
Example fix
# before — list of models summarizationProvider: deepseek summarizationModel: - deepseek-chat - deepseek-reasoner # after — single string summarizationProvider: deepseek summarizationModel: deepseek-chat
Defensive patterns
Strategy: type-guard
Type guard
function isOptionalString(v: unknown): v is string | undefined {
return v === undefined || typeof v === 'string'
}
// usage: isOptionalString(config.summarizationModel) Try / catch
try {
resolveConfig(config)
} catch (err) {
if ((err as Error).message.includes('summarizationModel must be a string')) {
throw new Error(
`summarizationModel: expected one model-name string or omit the key; got ${JSON.stringify(config.summarizationModel)}`,
{ cause: err },
)
}
throw err
} Prevention
- One model per config scope — no fallback lists at this key
- Quote model names in generated YAML and verify no numeric ids slip in
- Put per-route summarization models in that route's modelPolicies entry
When it happens
Trigger: 'summarizationModel:' with no value (YAML null), a numeric model id, or a list of candidate models (only one string is accepted, no fallback lists).
Common situations: Quoting or id mistakes when templating model names; trying to specify multiple fallback models as a list; assuming a default model fills in when the key is blank.
Related errors
- ${name}.summarizationProvider must be a string
- BasicCompactionConfig: auto must be a boolean
- BasicCompactionConfig: modelPolicies must be an array
- ${name} must be an object
- BasicCompactionConfig: ${policy.target.provider}/${policy.ta
AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24).
Data as JSON: /api/errors/d53d839912337bb7.
Report an issue: GitHub.