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

  1. Fix the underlying evaluation error reported by the wrapped %w cause — it names the real failure
  2. Simplify @cache arguments to plain literals, e.g. @cache(policy: "per-call", ttl: "5m")
  3. Check that any identifiers used in the @cache argument are defined and imported in the module scope
  4. 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

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


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/71e080dadc0f088d. Report an issue: GitHub.