vuejs/vue · error · Error

renderer cache must implement at least get & set.

Error message

renderer cache must implement at least get & set.

What it means

Thrown by the RenderContext constructor when the cache option is truthy but is missing either a get or a set method. The renderer's component caching mechanism calls cache.get and cache.set during renderComponentWithCache, so both must exist. A partial cache object (e.g. only has get, or is a plain object) is rejected because silent cache misses would degrade SSR performance without warning.

Source

Thrown at packages/server-renderer/src/render-context.ts:62

  get?: (key: string, cb: Function) => void
  has?: (key: string, cb: Function) => void

  constructor(options: Record<string, any>) {
    this.userContext = options.userContext
    this.activeInstance = options.activeInstance
    this.renderStates = []

    this.write = options.write
    this.done = options.done
    this.renderNode = options.renderNode

    this.isUnaryTag = options.isUnaryTag
    this.modules = options.modules
    this.directives = options.directives

    const cache = options.cache
    if (cache && (!cache.get || !cache.set)) {
      throw new Error('renderer cache must implement at least get & set.')
    }
    this.cache = cache
    this.get = cache && normalizeAsync(cache, 'get')
    this.has = cache && normalizeAsync(cache, 'has')

    this.next = this.next.bind(this)
  }

  next() {
    // eslint-disable-next-line
    while (true) {
      const lastState = this.renderStates[this.renderStates.length - 1]
      if (isUndef(lastState)) {
        return this.done()
      }
      /* eslint-disable no-case-declarations */
      switch (lastState.type) {
        case 'Element':

View on GitHub (pinned to 9e88707940)

Solutions

  1. Ensure the cache object implements both get(key, cb?) and set(key, val) as methods.
  2. Wrap external caches (Redis, LRU) in an adapter: { get: (k, cb) => redis.get(k, cb), set: (k, v) => redis.set(k, v) }.
  3. Pass undefined/null instead of a partial object if caching is not needed.
  4. Use lru-cache with a compatible adapter or the built-in pattern from Vue SSR docs.

Example fix

// before — raw object with no get/set
createRenderer({ cache: { ttl: 600 } })

// after — proper cache adapter
const LRU = require('lru-cache')
const lru = new LRU({ max: 1000, maxAge: 1000 * 60 * 15 })
createRenderer({
  cache: {
    get: (key, cb) => cb(lru.get(key)),
    set: (key, val) => lru.set(key, val),
    has: (key, cb) => cb(lru.has(key))
  }
})
Defensive patterns

Strategy: type-guard

Validate before calling

function isValidCache(cache: unknown): boolean {
  if (!cache) return true // no cache is valid
  return typeof (cache as any).get === 'function' && typeof (cache as any).set === 'function'
}

if (!isValidCache(options.cache)) {
  throw new Error('cache must have get and set methods')
}
createRenderer(options)

Type guard

type RenderCache = { get: (key: string, cb?: Function) => any; set: (key: string, val: string) => void; has?: (key: string, cb?: Function) => any }

function isRenderCache(v: unknown): v is RenderCache {
  if (typeof v !== 'object' || v === null) return false
  const c = v as Record<string, unknown>
  return typeof c.get === 'function' && typeof c.set === 'function'
}

Try / catch

// Thrown in RenderContext constructor, called synchronously inside render().
// Wrap the render call:
try {
  renderer.renderToString(app, cb)
} catch (e) {
  if (e.message.includes('renderer cache must implement')) {
    console.error('Fix cache adapter or remove the cache option')
  }
  throw e
}

Prevention

When it happens

Trigger: Calling createRenderer({ cache: someObject }) where someObject is truthy but lacks a get or set function. Typical with a half-implemented cache adapter, a plain Map passed wrongly (Map has get/set but they are prototype methods — still works), or a config object that was meant to configure a cache but was passed as the cache itself.

Common situations: Passing a Redis client object directly instead of wrapping it in a { get, set } adapter. Passing a configuration object { ttl: 1000 } by mistake. Using a stale cache API from an older version that had different method names.

Related errors


AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11). Data as JSON: /api/errors/e2a802c89de2e122. Report an issue: GitHub.