{"record":{"id":"f7c756a07bd65e6d","repo":"deepseek-ai/deepseek-harness","slug":"name-summarizationprovider-must-be-a-string","errorCode":null,"errorMessage":"${name}.summarizationProvider must be a string","messagePattern":"(.+?)\\.summarizationProvider must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/compaction/compaction-basic/src/config.ts","lineNumber":262,"sourceCode":"  if (compactionRetries !== undefined) {\n    assertNonNegativeInteger(`${name}.compactionRetries`, compactionRetries)\n  }\n  if (maxOverflowRetries !== undefined) {\n    assertNonNegativeInteger(`${name}.maxOverflowRetries`, maxOverflowRetries)\n  }\n\n  validateSummarizationPair(config, name)\n}\n\n/** Require one scope to omit, clear, or replace the summarization target as a pair. */\nfunction validateSummarizationPair(\n  config: CompactionPolicyConfig | Record<string, unknown>,\n  name: string,\n): void {\n  const provider = config.summarizationProvider\n  const model = config.summarizationModel\n  if (provider !== undefined && typeof provider !== 'string') {\n    throw new Error(`${name}.summarizationProvider must be a string`)\n  }\n  if (model !== undefined && typeof model !== 'string') {\n    throw new Error(`${name}.summarizationModel must be a string`)\n  }\n  if (provider === undefined && model === undefined) return\n  if (provider === undefined || model === undefined\n    || (provider.length === 0) !== (model.length === 0)) {\n    throw new Error(\n      `${name}: summarizationProvider and summarizationModel must be set together `\n      + 'as an empty or non-empty pair',\n    )\n  }\n}\n\n/** Reject stale or misspelled keys before defaults can hide them. */\nfunction validateKeys(config: object, keys: ReadonlySet<string>, name: string): void {\n  for (const key of Object.keys(config)) {\n    if (!keys.has(key)) throw new Error(`${name}: unknown key \"${key}\"`)","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/compaction/compaction-basic/src/config.ts#L244-L280","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before — key present but null, and half-set pair\nsummarizationProvider:\nsummarizationModel: deepseek-chat\n\n# after — proper non-empty pair\nsummarizationProvider: deepseek\nsummarizationModel: deepseek-chat","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isOptionalString(v: unknown): v is string | undefined {\n  return v === undefined || typeof v === 'string'\n}\n// usage: isOptionalString(config.summarizationProvider)","tryCatchPattern":"try {\n  resolveConfig(config)\n} catch (err) {\n  if ((err as Error).message.includes('summarizationProvider must be a string')) {\n    throw new Error(\n      `summarizationProvider: expected a provider-name string or omit the key; got ${JSON.stringify(config.summarizationProvider)}`,\n      { cause: err },\n    )\n  }\n  throw err\n}","preventionTips":["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"],"tags":["config","validation","yaml","type-mismatch","compaction"],"backgroundTag":"config-type-mismatch","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}