{"record":{"id":"845d8826a3c1e97a","repo":"deepseek-ai/deepseek-harness","slug":"name-must-be-an-object","errorCode":null,"errorMessage":"${name} must be an object","messagePattern":"(.+?) must be an object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/compaction/compaction-basic/src/config.ts","lineNumber":219,"sourceCode":"    const name = `BasicCompactionConfig: modelPolicies[${index}]`\n    assertModelPolicy(source, name)\n    const key = `${source.provider}\\u0000${source.model}`\n    if (seen.has(key)) {\n      throw new Error(\n        `BasicCompactionConfig: duplicate model policy for ${source.provider}/${source.model}`,\n      )\n    }\n    seen.add(key)\n    return { ...source }\n  })\n}\n\n/** Validate one untrusted exact-target override and narrow its public type. */\nfunction assertModelPolicy(\n  source: unknown,\n  name: string,\n): asserts source is ModelCompactPolicyConfig {\n  if (!isUnknownRecord(source)) throw new Error(`${name} must be an object`)\n  validateKeys(source, MODEL_POLICY_KEYS, name)\n  assertNonEmptyString(`${name}.provider`, source.provider)\n  assertNonEmptyString(`${name}.model`, source.model)\n  validatePolicy(source, name)\n}\n\n/** Validate the fields common to defaults and exact-target partial overrides. */\nfunction validatePolicy(\n  config: CompactionPolicyConfig | Record<string, unknown>,\n  name: string,\n): void {\n  const thresholdRatio = config.thresholdRatio\n  const retainRatio = config.retainRatio\n  const retainTokens = config.retainTokens\n  const maxTokens = config.maxTokens\n  const compactionRetries = config.compactionRetries\n  const maxOverflowRetries = config.maxOverflowRetries\n  if (thresholdRatio !== undefined) assertRatio(`${name}.thresholdRatio`, thresholdRatio)","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/compaction/compaction-basic/src/config.ts#L201-L237","documentation":"Every element of the modelPolicies array is validated by assertModelPolicy() before use. An element that is not a plain object — a string, number, boolean, null, or nested array — fails the '${name} must be an object' check, where name is 'BasicCompactionConfig: modelPolicies[<index>]' pointing at the exact bad element.","triggerScenarios":"A list item that is a shorthand string (e.g. '- deepseek/deepseek-chat'), a bare scalar ('- 16384'), a null placeholder ('- ~' or an empty '- '), or a nested sequence. Only mapping items ('- provider: x') pass.","commonSituations":"Trying a compact 'provider/model' string syntax the plugin does not support; YAML indentation that puts a value on its own list item; JSON configs where an entry got replaced by its model name string.","solutions":["Make each list item an object with explicit provider and model fields plus optional policy fields","Remove null or placeholder entries from the list","Check YAML indentation: every item under modelPolicies must start with '- provider:'"],"exampleFix":"# before — shorthand string entries\nmodelPolicies:\n  - deepseek/deepseek-chat\n  - deepseek/deepseek-reasoner\n\n# after — object entries\nmodelPolicies:\n  - provider: deepseek\n    model: deepseek-chat\n  - provider: deepseek\n    model: deepseek-reasoner","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isModelPolicyCandidate(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n// usage: (config.modelPolicies ?? []).every(isModelPolicyCandidate)","tryCatchPattern":"try {\n  resolveConfig(config)\n} catch (err) {\n  const idx = (err as Error).message.match(/modelPolicies\\[(\\d+)\\] must be an object/)?.[1]\n  if (idx !== undefined) {\n    throw new Error(\n      `modelPolicies[${idx}] is not an object: ${JSON.stringify(config.modelPolicies?.[+idx])} — use { provider, model, ...policy }`,\n      { cause: err },\n    )\n  }\n  throw err\n}","preventionTips":["Never use 'provider/model' shorthand strings — the schema requires both as object fields","Lint YAML so every modelPolicies item starts with '- provider:'","Type the array in TypeScript so string entries fail to compile"],"tags":["config","validation","yaml","plugin-config","compaction"],"backgroundTag":"config-type-mismatch","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}