deepseek-ai/deepseek-harness · error

${name} (${String(value)}) must be a positive integer

Error message

${name} (${String(value)}) must be a positive integer

What it means

maxTokens — the ceiling on the post-compaction summary plus retained tail — is validated by assertPositiveInteger: it must be a finite integer greater than 0, and the message echoes the offending value. Zero, negatives, fractional numbers, numeric strings, NaN, and Infinity all fail. Omitting the key uses the default 8192.

Source

Thrown at packages/compaction/compaction-basic/src/config.ts:296

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}"`)
  }
}

function isUnknownRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value)
}

function assertNonEmptyString(name: string, value: unknown): asserts value is string {
  if (typeof value !== 'string' || value.length === 0) {
    throw new Error(`${name} must be a non-empty string`)
  }
}

function assertPositiveInteger(name: string, value: unknown): asserts value is number {
  if (typeof value !== 'number' || !Number.isInteger(value) || value <= 0) {
    throw new Error(`${name} (${String(value)}) must be a positive integer`)
  }
}

function assertNonNegativeInteger(name: string, value: unknown): asserts value is number {
  if (typeof value !== 'number' || !Number.isInteger(value) || value < 0) {
    throw new Error(`${name} (${String(value)}) must be a non-negative integer`)
  }
}

function assertRatio(name: string, value: unknown): asserts value is number {
  if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0 || value > 1) {
    throw new Error(`${name} (${String(value)}) must be a number in (0, 1]`)
  }
}

View on GitHub (pinned to b150a551b8)

Solutions

  1. Set a positive integer such as 16384, or remove the key to use the 8192 default
  2. Unquote numeric values in YAML/JSON pipelines
  3. When computing the value, verify Number.isInteger(v) && v > 0 before assigning it to the config

Example fix

# before
maxTokens: '16384'   # string, not number

# after
maxTokens: 16384
Defensive patterns

Strategy: type-guard

Type guard

function isPositiveInteger(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && v > 0
}
// usage: config.maxTokens === undefined || isPositiveInteger(config.maxTokens)

Try / catch

try {
  resolveConfig(config)
} catch (err) {
  const hit = (err as Error).message.match(/(.+) \(\(.*\)\) must be a positive integer/)
  if (hit !== undefined) {
    throw new Error(
      `${hit[1]}: pass an unquoted integer > 0 (0, negatives, floats, and strings are rejected)`,
      { cause: err },
    )
  }
  throw err
}

Prevention

When it happens

Trigger: maxTokens: 0 (attempting to disable), a negative or fractional value, a quoted number ('16384') from YAML/JSON templating, or a computed value that yields NaN or Infinity.

Common situations: Quoting numbers when generating configs; arithmetic on environment variables producing floats; carrying over a '0 means unlimited' convention from another system — here there is no unlimited value.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/e55a472a7191e786. Report an issue: GitHub.