Skip to content

Fix type assertion panic in Cache.Get() when key not found#881

Merged
mattisonchao merged 3 commits intooxia-db:mainfrom
labuladong:fix/cache-type-assertion-panic
Feb 6, 2026
Merged

Fix type assertion panic in Cache.Get() when key not found#881
mattisonchao merged 3 commits intooxia-db:mainfrom
labuladong:fix/cache-type-assertion-panic

Conversation

@labuladong
Copy link
Copy Markdown
Contributor

Summary

Fix a type assertion panic that occurs when Cache.Get() is called for a key that doesn't exist in Oxia.

Problem

When a key is not found, the cache stores a negative cache entry using:

cr := empty[cachedResult[Value]]()

However, cachedResult[Value] is a type alias for Optional[valueVersion[Value]], so this creates a double-wrapped optional type:

*optional[Optional[valueVersion[Value]]]

When Cache.Get() later retrieves this entry and attempts the type assertion:

cachedValue.(cachedResult[Value])

It fails with:

interface conversion: *oxia.optional[cachedResult[...]] is not cachedResult[...]: missing method Get

Solution

Use empty[valueVersion[Value]]() instead, which creates *optional[valueVersion[Value]] - the same type structure as the non-empty case, ensuring type consistency.

Type Analysis

cachedResult[Value] = Optional[valueVersion[Value]]  // type alias

// Before (BUG):
empty[cachedResult[Value]]() 
= empty[Optional[valueVersion[Value]]]()
= *optional[Optional[valueVersion[Value]]]  // double-wrapped!

// After (FIX):
empty[valueVersion[Value]]()
= *optional[valueVersion[Value]]  // correct, matches non-empty case

When a key is not found in Oxia, the cache stores a negative cache entry
using `empty[cachedResult[Value]]()`. However, since cachedResult[Value]
is a type alias for Optional[valueVersion[Value]], this creates a
double-wrapped optional type: *optional[Optional[valueVersion[Value]]].

When Cache.Get() later retrieves this entry and attempts the type
assertion `cachedValue.(cachedResult[Value])`, it fails with:
"interface conversion: *oxia.optional[cachedResult[...]] is not
cachedResult[...]: missing method Get"

The fix is to use `empty[valueVersion[Value]]()` instead, which creates
*optional[valueVersion[Value]] - the same type structure as the non-empty
case, ensuring type consistency.
@mattisonchao
Copy link
Copy Markdown
Member

Hi @labuladong

could you hellp add a test for it?

TestCache_GetNotFoundTwice: Verifies that calling Get() twice on a
non-existing key does not panic. The first call stores a negative
cache entry via load(), the second call reads it from ristretto and
performs a type assertion that would fail with the old code.

TestCache_GetNotFoundThenPut: Verifies that a key can transition from
"not found" (negative cache entry) to a valid value without issues.
@labuladong labuladong force-pushed the fix/cache-type-assertion-panic branch from fe79297 to d42f605 Compare February 6, 2026 02:27
@mattisonchao mattisonchao merged commit db9eb26 into oxia-db:main Feb 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants