Skip to content

[cache] @cache raises TypeError for unhashable arguments (e.g. Pydantic model inputs) #59

Closed

Description

@Shreyavemana

Summary

In nitrostack/core/additional_decorators.py, @cache builds its cache key directly from positional and keyword arguments. When an argument is unhashable, such as a non-frozen Pydantic v2 model, the cache lookup raises TypeError instead of executing the function.

Findings

  • cache() filters out ExecutionContext arguments but retains other arguments in their original form.
  • The cache key is constructed using tuple(filtered_args) and frozenset(filtered_kwargs.items()). Both structures require their contents to be hashable.
  • When a Pydantic model is passed as an argument, checking whether the key exists in cache_store can raise TypeError: unhashable type.
  • This affects cached tool methods that receive Pydantic input models and other functions that accept unhashable arguments.
  • The current implementation does not provide a custom key function or a clear error explaining which argument caused the failure.

Proposal

  1. Serialize Pydantic BaseModel arguments using model_dump(mode="json") and generate a deterministic cache key from the serialized data.
  2. Add an optional key= callable to cache() so developers can define cache keys for custom argument types.
  3. Raise a clear, descriptive error identifying the unhashable argument and its type when a valid cache key cannot be constructed.
  4. Add tests covering Pydantic models, unhashable positional and keyword arguments, and custom key functions.

Activity

  1. self-assigned this
    on Nov 4, 2026
  2. manish-wekan commented on Nov 5, 2026

    @manish-wekan
    Collaborator

    Fixed by #110 (merge ca3e7b8 on develop). Verified both cases from the review: exclude=True fields are part of the cache key, and same-named models from different scopes no longer collide. Full suite on develop @ 331bebe: 1338 passed.

    ~sent from claude-code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions