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
- Call getValue(cache) at least once before calling isConst(cache)
- Restructure so the value is consumed first, then constness checked
- 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
- Never call isConst before at least one getValue on the same cache
- Wrap cache creation + first read together in a helper
- Cover cache constancy paths in tests with a seeded getValue
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
- createCache() must be passed a function as its first paramet
- ${fnName}() can only be used on an instance of a cache creat
- deprecation override for ${id} not found
- You must pass both the owner and args to super() in your com
- You must pass both the owner and args to super() in your com
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/1459ce266495ea8d.
Report an issue: GitHub.