dagger/dagger · error
failed to evaluate @cache argument %s: %w
Error message
failed to evaluate @cache argument %s: %w
What it means
This error wraps any failure that occurs while evaluating an argument passed to the @cache directive in a Dang function definition. The Dang SDK evaluates @cache directive arguments (policy, ttl) at function-creation time via evalDirectiveArg; if that evaluation fails (e.g. the expression errors, references undefined names, or produces an invalid value), the failure is wrapped with the offending argument key so the developer knows which @cache argument was bad.
Source
Thrown at core/sdk/dang/v2/helpers.go:735
case "cache":
sel, err := cacheDirectiveSelector(ctx, env, directive)
if err != nil {
return nil, err
}
sels = append(sels, sel)
}
}
return sels, nil
}
// cacheDirectiveSelector converts a @cache directive into a withCachePolicy selector.
func cacheDirectiveSelector(ctx context.Context, env dang.ValueScope, directive *dang.DirectiveApplication) (dagql.Selector, error) {
var policy core.FunctionCachePolicy
var ttl string
for _, arg := range directive.Args {
val, err := evalDirectiveArg(ctx, env, arg.Value)
if err != nil {
return dagql.Selector{}, fmt.Errorf("failed to evaluate @cache argument %s: %w", arg.Key, err)
}
switch arg.Key {
case "policy":
if s, ok := val.(string); ok {
policy = core.FunctionCachePolicy(s)
}
case "ttl":
if s, ok := val.(string); ok {
ttl = s
}
}
}
if policy == "" {
policy = core.FunctionCachePolicyDefault
}
args := []dagql.NamedInput{
{Name: "policy", Value: policy},
}View on GitHub (pinned to 82ba2681db)
Solutions
- Fix the underlying evaluation error reported by the wrapped %w cause — it names the real failure
- Simplify @cache arguments to plain literals, e.g. @cache(policy: "per-call", ttl: "5m")
- Check that any identifiers used in the @cache argument are defined and imported in the module scope
- Verify the argument key is one the directive supports (policy, ttl)
Example fix
// before
@cache(policy: cachePolicy, ttl: ttlFromEnv)
func build(): Container { ... }
// after
@cache(policy: "per-call", ttl: "5m")
func build(): Container { ... } Defensive patterns
Strategy: validation
Validate before calling
// Prefer literal arguments in @cache so evaluation cannot fail:
// @cache(policy: "per-call", ttl: "5m")
func validateCacheArgs(policy any, ttl any) error {
if policy != nil {
if _, ok := policy.(string); !ok {
return fmt.Errorf("@cache policy must be a string, got %T", policy)
}
}
if ttl != nil {
if _, ok := ttl.(string); !ok {
return fmt.Errorf("@cache ttl must be a string, got %T", ttl)
}
}
return nil
} Type guard
func isString(v any) bool { _, ok := v.(string); return ok } Try / catch
sel, err := cacheDirectiveSelector(ctx, env, directive)
if err != nil {
var evalErr *evalError
if errors.As(err, &evalErr) {
// fall back to default cache policy or skip function creation
}
return fmt.Errorf("cache directive on function: %w", err)
} Prevention
- Use plain string literals for @cache policy and ttl
- Keep directive arguments free of runtime-dependent expressions
- Verify identifiers used in directive arguments exist in module scope
When it happens
Trigger: Declaring a function with @cache(policy: ..., ttl: ...) where the argument expression fails to evaluate — e.g. referencing an undefined variable, calling a function that errors, or a literal that cannot be resolved in the current ValueScope.
Common situations: Typo in a variable name inside a @cache argument; using a non-literal expression that depends on runtime values not available when the module is loaded; copying an example with ttl/policy expressions that reference helpers not imported in scope.
Related errors
- @defaultPath.path for %s: %w
- @ignorePatterns.patterns for %s: %w
- evaluate changeset diff directory: %w
- diff snapshot: %w
- evaluate structural diff: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/71e080dadc0f088d.
Report an issue: GitHub.