Fix: Not a Valid Number for Duration in Vue.js

Error message:
{type} is not a valid number - got {value}.
Components 2025-01-25

What Causes This Warning?

This warning occurs when you pass an invalid value for transition duration properties. Vue expects numbers (milliseconds) but receives strings or other invalid types.

The Problem

<!-- ❌ Invalid duration values -->
<template>
  <Transition :duration="'500'">  <!-- String instead of number -->
    <div v-if="show">Content</div>
  </Transition>

  <Transition :duration="'fast'">  <!-- Non-numeric string -->
    <div v-if="show">Content</div>
  </Transition>
</template>

The Fix

Use Number Values

<template>
  <!-- ✅ Number value in milliseconds -->
  <Transition :duration="500">
    <div v-if="show">Content</div>
  </Transition>

  <!-- ✅ Separate enter/leave durations -->
  <Transition :duration="{ enter: 300, leave: 500 }">
    <div v-if="show">Content</div>
  </Transition>
</template>

Dynamic Duration

<script setup>
import { ref, computed } from 'vue'

const speed = ref('normal')

// ✅ Convert to numbers
const duration = computed(() => {
  const durations = {
    fast: 200,
    normal: 400,
    slow: 800
  }
  return durations[speed.value] || 400
})
</script>

<template>
  <Transition :duration="duration">
    <div v-if="show">Content</div>
  </Transition>
</template>

Common Scenarios

Parsing User Input

<script setup>
const userDuration = ref('500')

// ❌ Passing string directly
// :duration="userDuration"

// ✅ Parse to number
const duration = computed(() => {
  const parsed = parseInt(userDuration.value, 10)
  return isNaN(parsed) ? 400 : parsed
})
</script>

API Response

// ❌ API might return strings
const config = await fetchConfig()
// config.duration = "300"

// ✅ Convert to number
const duration = Number(config.duration) || 400

Transition Group

<template>
  <!-- ✅ Valid duration for TransitionGroup -->
  <TransitionGroup name="list" :duration="300">
    <div v-for="item in items" :key="item.id">
      {{ item.name }}
    </div>
  </TransitionGroup>
</template>

Object Duration Format

<template>
  <!-- ✅ Different durations for enter/leave -->
  <Transition
    :duration="{
      enter: 500,
      leave: 200
    }"
  >
    <modal v-if="showModal" />
  </Transition>
</template>

CSS vs JS Duration

<template>
  <!-- When using CSS transitions, duration prop overrides CSS -->
  <Transition name="fade" :duration="500">
    <div v-if="show">Content</div>
  </Transition>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s; /* Overridden by :duration="500" */
}
</style>

Quick Checklist

  • Use numbers, not strings for duration
  • Duration is in milliseconds (500 = 0.5 seconds)
  • Parse string inputs with parseInt() or Number()
  • Validate API responses before using
  • Use object syntax for different enter/leave durations