vitest-dev/vitest · error · TypeError

Tag "${tag.name}": priority must be a non-negative number.

Error message

Tag "${tag.name}": priority must be a non-negative number.

What it means

Thrown when a tag's `priority` field is present but is not a number, or is a negative number. Priority controls tag evaluation ordering and must be a non-negative numeric value. The guard at resolveConfig.ts:279 rejects undefined-coerced values, strings, and negatives before they corrupt sort order downstream.

Source

Thrown at packages/vitest/src/node/config/resolveConfig.ts:280

      throw new Error(`Each tag defined in "test.tags" must have a "name" property, received: ${JSON.stringify(tag)}`)
    }
    if (definedTags.has(tag.name)) {
      throw new Error(`Tag name "${tag.name}" is already defined in "test.tags". Tag names must be unique.`)
    }
    if (/\s/.test(tag.name)) {
      throw new Error(`Tag name "${tag.name}" is invalid. Tag names cannot contain spaces.`)
    }
    if (/[!()*|&]/.test(tag.name)) {
      throw new Error(`Tag name "${tag.name}" is invalid. Tag names cannot contain "!", "*", "&", "|", "(", or ")".`)
    }
    if (/^\s*(?:and|or|not)\s*$/i.test(tag.name)) {
      throw new Error(`Tag name "${tag.name}" is invalid. Tag names cannot be a logical operator like "and", "or", "not".`)
    }
    if (typeof tag.retry === 'object' && typeof tag.retry.condition === 'function') {
      throw new TypeError(`Tag "${tag.name}": retry.condition function cannot be used inside a config file. Use a RegExp pattern instead, or define the function in your test file.`)
    }
    if (tag.priority != null && (typeof tag.priority !== 'number' || tag.priority < 0)) {
      throw new TypeError(`Tag "${tag.name}": priority must be a non-negative number.`)
    }
    definedTags.add(tag.name)
  })

  resolved.name = typeof options.name === 'string'
    ? options.name
    : (options.name?.label || '')

  resolved.color = typeof options.name !== 'string' ? options.name?.color : undefined

  if (resolved.environment === 'browser') {
    throw new Error(`Looks like you set "test.environment" to "browser". To enable Browser Mode, use "test.browser.enabled" instead.`)
  }

  resolved.benchmark = {
    ...benchmarkConfigDefaults,
    ...resolved.benchmark,
  }

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Set priority to a non-negative integer: `priority: 0` (or higher).
  2. Remove the priority field entirely if you do not need ordering control.
  3. If you used negatives for 'run last', invert your scheme so larger numbers run first and start at 0.

Example fix

// before
tags: [{ name: 'smoke', priority: -5 }]
// after
tags: [{ name: 'smoke', priority: 0 }]
Defensive patterns

Strategy: validation

Validate before calling

function assertValidPriority(tags: any[]) {
  for (const t of tags) {
    if (t.priority != null && (typeof t.priority !== 'number' || t.priority < 0)) {
      throw new Error(`Tag "${t.name}": priority must be a non-negative number, got ${JSON.stringify(t.priority)}`)
    }
  }
}

Type guard

function hasValidPriority(tag: any): boolean {
  return tag.priority == null || (typeof tag.priority === 'number' && tag.priority >= 0 && Number.isFinite(tag.priority))
}

Prevention

When it happens

Trigger: Set `tags: [{ name: 'smoke', priority: -1 }]` or `tags: [{ name: 'smoke', priority: 'high' }]`. The check fires because priority is non-null and either not a number or less than 0.

Common situations: Treating priority as a label/string; using negative numbers to mean 'lowest'; copy-paste from another tool's schema.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/ac94c174374e760e.json. Report an issue: GitHub.