emberjs/ember.js · error · Error

isConst() can only be used on a cache once getValue() has be

Error message

isConst() can only be used on a cache once getValue() has been called at least once. Called with cache function:\n\n${String(cache[FN])}

What it means

isConst() checks whether a cache's tag is still valid without invalidating it, but the tag only exists after getValue() has run at least once. In DEBUG builds, if the cache's internal tag is undefined, isConst throws telling you the cache function was never evaluated.

Source

Thrown at packages/@glimmer/validator/lib/tracking.ts:217

function assertCache<T>(
  value: Cache<T> | InternalCache<T>,
  fnName: string
): asserts value is InternalCache<T> {
  if (DEBUG && !(typeof value === 'object' && FN in value)) {
    throw new Error(
      `${fnName}() can only be used on an instance of a cache created with createCache(). Called with: ${String(
        // eslint-disable-next-line @typescript-eslint/no-base-to-string -- @fixme
        value
      )}`
    );
  }
}

// replace this with `expect` when we can
function assertTag(tag: Tag | undefined, cache: InternalCache): asserts tag is Tag {
  if (DEBUG && tag === undefined) {
    throw new Error(
      `isConst() can only be used on a cache once getValue() has been called at least once. Called with cache function:\n\n${String(
        cache[FN]
      )}`
    );
  }
}

//////////

// Legacy tracking APIs

// track() shouldn't be necessary at all in the VM once the autotracking
// refactors are merged, and we should generally be moving away from it. It may
// be necessary in Ember for a while longer, but I think we'll be able to drop
// it in favor of cache sooner rather than later.
export function track(block: () => void, debugLabel?: string | false): Tag {
  beginTrackFrame(debugLabel);

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Call getValue(cache) at least once before calling isConst(cache)
  2. Restructure so the value is consumed first, then constness checked
  3. In tests, seed the cache with a getValue call before asserting isConst

Example fix

// before
if (isConst(cache)) { hoist(); }
// after
getValue(cache);
if (isConst(cache)) { hoist(); }
Defensive patterns

Strategy: validation

Validate before calling

let tag; const value = getValue(cache); // must run before isConst
if (isConst(cache)) { hoist(value); }

Try / catch

try { return isConst(cache); } catch (e) { if (String(e).includes('getValue()')) { getValue(cache); return isConst(cache); } throw e; }

Prevention

When it happens

Trigger: Calling isConst(cache) before ever calling getValue(cache) on the same cache object.

Common situations: Conditional code paths where isConst is checked eagerly on first render; unit tests asserting constness without seeding the cache; moving isConst earlier during refactors.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/1459ce266495ea8d. Report an issue: GitHub.