deepseek-ai/deepseek-harness · error
${name}.summarizationProvider must be a string
Error message
${name}.summarizationProvider must be a string What it means
summarizationProvider names the LLM provider used to summarize during compaction. validateSummarizationPair() requires that when the key is present it is a string; numbers, booleans, objects, and null all fail. The key is also bound to the pair rule with summarizationModel (set together, or both empty, or both omitted).
Source
Thrown at packages/compaction/compaction-basic/src/config.ts:262
if (compactionRetries !== undefined) {
assertNonNegativeInteger(`${name}.compactionRetries`, compactionRetries)
}
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 summarizationProvider to a non-empty provider-name string together with summarizationModel
- To leave it unset, remove the key entirely; to explicitly clear inheritance in a modelPolicies entry, set both fields to ''
- Fix the YAML so the value is a plain string on one line
Example fix
# before — key present but null, and half-set pair summarizationProvider: summarizationModel: deepseek-chat # after — proper non-empty pair 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.summarizationProvider) Try / catch
try {
resolveConfig(config)
} catch (err) {
if ((err as Error).message.includes('summarizationProvider must be a string')) {
throw new Error(
`summarizationProvider: expected a provider-name string or omit the key; got ${JSON.stringify(config.summarizationProvider)}`,
{ cause: err },
)
}
throw err
} Prevention
- Omit the key to unset it — never leave it empty in YAML
- After YAML loading, map null to undefined before it reaches the validator
- Keep provider identifiers as strings end to end in config pipelines
When it happens
Trigger: cordis.yml 'summarizationProvider:' with no value (YAML null, if it survives the loader as null), a numeric provider id, a boolean, or an inline mapping; programmatic config assigning a non-string variable.
Common situations: Leaving the key empty intending 'unset' — the correct unset is omitting the key; using provider indices/enums from another system; templating that emits null for missing values.
Related errors
- ${name}.summarizationModel 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/f7c756a07bd65e6d.
Report an issue: GitHub.