{"record":{"id":"8b8bae890e550f44","repo":"deepseek-ai/deepseek-harness","slug":"name-must-be-a-non-empty-string","errorCode":null,"errorMessage":"${name} must be a non-empty string","messagePattern":"(.+?) must be a non-empty string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/compaction/compaction-basic/src/config.ts","lineNumber":290,"sourceCode":"      + '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}\"`)\n  }\n}\n\nfunction isUnknownRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction assertNonEmptyString(name: string, value: unknown): asserts value is string {\n  if (typeof value !== 'string' || value.length === 0) {\n    throw new Error(`${name} must be a non-empty string`)\n  }\n}\n\nfunction assertPositiveInteger(name: string, value: unknown): asserts value is number {\n  if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {\n    throw new Error(`${name} (${String(value)}) must be a positive integer`)\n  }\n}\n\nfunction assertNonNegativeInteger(name: string, value: unknown): asserts value is number {\n  if (typeof value !== 'number' || !Number.isInteger(value) || value < 0) {\n    throw new Error(`${name} (${String(value)}) must be a non-negative integer`)\n  }\n}\n\nfunction assertRatio(name: string, value: unknown): asserts value is number {\n  if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0 || value > 1) {\n    throw new Error(`${name} (${String(value)}) must be a number in (0, 1]`)","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/compaction/compaction-basic/src/config.ts#L272-L308","documentation":"Inside each modelPolicies entry, provider and model form the exact route key and must be non-empty strings (assertNonEmptyString). The check fires for '' and for non-strings (numbers, booleans, null) alike, because an empty route can never match a real provider/model. The name in the message is 'BasicCompactionConfig: modelPolicies[<i>].provider' or '.model'.","triggerScenarios":"A modelPolicies entry with 'provider:' or 'model:' left empty in YAML (null), set to '', or set to a non-string value; template or env substitution producing an empty identifier.","commonSituations":"Placeholder entries awaiting real model names; env-driven config where the variable is unset and interpolates to ''; refactoring that moves provider into a variable that is sometimes empty.","solutions":["Fill in real non-empty provider and model strings","Remove placeholder entries until the route is known","Guard env/template-driven config so an empty substitution drops the whole entry instead of shipping it"],"exampleFix":"# before — empty route key\nmodelPolicies:\n  - provider: deepseek\n    model: ''\n    maxTokens: 16384\n\n# after\nmodelPolicies:\n  - provider: deepseek\n    model: deepseek-chat\n    maxTokens: 16384","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isNonEmptyString(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0\n}\n// usage: modelPolicies.every(p => isNonEmptyString(p.provider) && isNonEmptyString(p.model))","tryCatchPattern":"try {\n  resolveConfig(config)\n} catch (err) {\n  const m = (err as Error).message\n  const hit = m.match(/modelPolicies\\[(\\d+)\\]\\.(provider|model) must be a non-empty string/)\n  if (hit !== undefined) {\n    throw new Error(\n      `modelPolicies[${hit[1]}].${hit[2]} is empty or not a string — fill in the real route value`,\n      { cause: err },\n    )\n  }\n  throw err\n}","preventionTips":["Never ship placeholder empty-string routes — comment the entry out until the model name is known","Default env substitutions so unset variables fail loudly instead of yielding an empty string","Check that programmatic route builders receive string provider/model, not ids or nulls"],"tags":["config","validation","empty-string","plugin-config","compaction"],"backgroundTag":"non-empty-string-validation","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}