mastra-ai/mastra · error
${key} exists but is not a number
Error message
${key} exists but is not a number What it means
InMemoryCache.increment reads the current value at the key, adds 1, and writes it back. If the stored value exists but is not a number (string, object, array), it throws instead of coercing, preventing silent data corruption of counters.
Source
Thrown at packages/core/src/cache/inmemory.ts:105
}
async delete(key: string): Promise<void> {
this.cache.delete(key);
}
async clear(): Promise<void> {
this.cache.clear();
}
async increment(key: string): Promise<number> {
const value = this.cache.get(key);
let counter: number;
if (value === undefined) {
counter = 1;
} else if (typeof value === 'number') {
counter = value + 1;
} else {
throw new Error(`${key} exists but is not a number`);
}
this.cache.set(key, counter);
return counter;
}
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Use a dedicated key namespace for counters (e.g. 'count:...') distinct from list/string keys
- Delete the existing non-numeric key before incrementing to reset the counter
- Call cache.set(key, 0) first if you need to reset the counter explicitly
Example fix
// before
await cache.set('visits', 'many');
await cache.increment('visits'); // throws
// after
await cache.set('visits', 0);
await cache.increment('visits'); // 1 Defensive patterns
Strategy: validation
Validate before calling
const current = await cache.get(key);
if (current !== undefined && typeof current !== 'number') {
throw new TypeError(`Key ${key} is not a numeric counter; reset it before incrementing`);
}
await cache.increment(key); Type guard
function isNumberCacheValue(v: unknown): v is number {
return typeof v === 'number';
} Try / catch
try {
await cache.increment(key);
} catch (err) {
if (err instanceof Error && err.message.includes('is not a number')) {
await cache.set(key, 0);
await cache.increment(key);
} else throw err;
} Prevention
- Reserve distinct key prefixes for counters
- Only store numbers under counter keys
- Reset with set(key, 0) when re-purposing a key
When it happens
Trigger: Calling await cache.increment(key) when the key was previously set via cache.set(key, 'some-string') or listPush(key, ...), so the existing value is not numeric.
Common situations: Key collisions between a list/scalar writer and a counter writer, refactored code that changed the value shape stored under a key, or serialized cache data restored with the wrong types.
Related errors
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/bdae5138d8ba1d50.
Report an issue: GitHub.