moeru-ai/airi · warning

version ${rawValue.value.version} doesn't satisfy the versio

Error message

version ${rawValue.value.version} doesn't satisfy the version ${defaultVersion} for key ${key}, will reset the value to default value ${toValue(initialValue)}

What it means

use-versioned-local-storage persists { version, data } envelopes in localStorage. On read, if the stored version fails the satisfiesVersionBy check against the current defaultVersion and no onVersionMismatch handler is configured, the stored data is discarded: both the storage value and the reactive data reset to initialValue, and this warning records the discarded version and the reset value.

Source

Thrown at packages/stage-shared/src/composables/use-versioned-local-storage/index.ts:53

  }, {
    deep: true,
  })

  watch(rawValue, (value) => {
    try {
      if ('version' in rawValue.value && rawValue.value.version != null) {
        if (options?.satisfiesVersionBy != null && !options.satisfiesVersionBy(rawValue.value.version, defaultVersion)) {
          if (options.onVersionMismatch != null) {
            const action = options.onVersionMismatch(rawValue.value)
            if (action.action === 'reset') {
              rawValue.value = { version: defaultVersion, data: toValue(initialValue) }
              syncDataToStorage.pause()
              data.value = toValue(initialValue)
              syncDataToStorage.resume()
            }
          }
          else {
            console.warn(`version ${rawValue.value.version} doesn't satisfy the version ${defaultVersion} for key ${key}, will reset the value to default value ${toValue(initialValue)}`)
            rawValue.value = { version: defaultVersion, data: toValue(initialValue) }
            syncDataToStorage.pause()
            data.value = toValue(initialValue)
            syncDataToStorage.resume()
          }
        }

        syncDataToStorage.pause()
        data.value = rawValue.value.data!
        syncDataToStorage.resume()
        return
      }

      console.warn(`property key 'version' wasn't found in the value of key ${key} as ${value}, will keep the current ${toValue(initialValue)}`)
      rawValue.value = { version: defaultVersion, data: toValue(initialValue) }
      syncDataToStorage.pause()
      data.value = toValue(initialValue)
      syncDataToStorage.resume()

View on GitHub (pinned to 677329427f)

Solutions

  1. Provide an onVersionMismatch handler that migrates rawValue.data to the new shape (return { action: 'migrate', value }) instead of accepting the reset
  2. Fix satisfiesVersionBy to accept every still-compatible version, not just the default
  3. Bump defaultVersion whenever the stored data shape changes so old envelopes are detected at all

Example fix

// before
useVersionedLocalStorage('my-key', defaultValue, {
  version: 2,
  // no satisfies/onMismatch -> v1 users silently reset to default
})

// after
useVersionedLocalStorage('my-key', defaultValue, {
  version: 2,
  satisfiesVersionBy: v => v >= 1,
  onVersionMismatch: (raw) => {
    const migrated = migrateFromV1(raw.data)
    return { action: 'migrate', value: migrated }
  },
})
Defensive patterns

Strategy: fallback

Validate before calling

const stored = JSON.parse(localStorage.getItem(key) ?? 'null')
if (stored && satisfiesVersionBy(stored.version, targetVersion)) {
  // safe: current code understands the stored version
}

Type guard

function isVersionedEnvelope(value: unknown): value is { version: number, data: unknown } {
  return typeof value === 'object' && value !== null
    && typeof (value as { version?: unknown }).version === 'number'
    && 'data' in value
}

Prevention

When it happens

Trigger: Bumping defaultVersion (or tightening satisfiesVersionBy) after users already have older-version data in the key; writing a satisfiesVersionBy predicate that rejects versions you actually consider compatible (e.g. exact equality instead of a range).

Common situations: Shipping a settings-schema change without a migration step; versioning a composable for the first time on a key that already had versioned data from an earlier experiment; predicate bugs that use !== against semver strings.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/b7e9d24da9b0d9b1. Report an issue: GitHub.