dagger/dagger · error

implicit input %q resolved to nil

Error message

implicit input %q resolved to nil

What it means

An ImplicitInput resolver completed without error but returned a nil Input value. dagql requires implicit inputs to resolve to a concrete value because they are attached to every cached call; a nil would be meaningless as a cache key/argument, so the call is rejected (dagql/objects.go:982).

Source

Thrown at dagql/objects.go:982

		def.Directives = append(def.Directives, experimental(spec.ExperimentalReason))
	}
	return def
}

func (spec *FieldSpec) resolveImplicitInputCallArgs(ctx context.Context, inputArgs map[string]Input) ([]*ResultCallArg, error) {
	if spec == nil || len(spec.ImplicitInputs) == 0 {
		return nil, nil
	}

	inputIdxByName := make(map[string]int, len(spec.ImplicitInputs))
	implicitArgs := make([]*ResultCallArg, 0, len(spec.ImplicitInputs))
	for _, implicitInput := range spec.ImplicitInputs {
		inputVal, err := implicitInput.Resolver(ctx, inputArgs)
		if err != nil {
			return nil, fmt.Errorf("resolve implicit input %q: %w", implicitInput.Name, err)
		}
		if inputVal == nil {
			return nil, fmt.Errorf("implicit input %q resolved to nil", implicitInput.Name)
		}

		newInput, err := resultCallArgFromInput(ctx, implicitInput.Name, inputVal, false)
		if err != nil {
			return nil, fmt.Errorf("resolve implicit input %q: %w", implicitInput.Name, err)
		}
		if idx, ok := inputIdxByName[implicitInput.Name]; ok {
			implicitArgs[idx] = newInput
			continue
		}
		inputIdxByName[implicitInput.Name] = len(implicitArgs)
		implicitArgs = append(implicitArgs, newInput)
	}
	sort.Slice(implicitArgs, func(i, j int) bool {
		return implicitArgs[i].Name < implicitArgs[j].Name
	})
	return implicitArgs, nil
}

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Change the resolver to return a valid default Input when the underlying value is absent.
  2. Explicitly return an error instead of (nil, nil) when the value genuinely cannot be resolved, so the message is actionable.
  3. If using a typed pointer, ensure you convert it to a non-nil typed Input value before returning.

Example fix

// before
func resolve(ctx context.Context, args InputArgs) (Input, error) {
    v := lookup(ctx)
    return v, nil // nil when lookup fails
}
// after
func resolve(ctx context.Context, args InputArgs) (Input, error) {
    v := lookup(ctx)
    if v == nil { return dagql.String("default"), nil }
    return v, nil
}
Defensive patterns

Strategy: validation

Validate before calling

val, err := resolver(ctx, args)
if err != nil { return err }
if val == nil { return fmt.Errorf("implicit input %q resolved to nil", name) }

Prevention

When it happens

Trigger: A custom ImplicitInput whose Resolver returns `nil, nil` — e.g. an optional implicit value where the author forgot to return a typed default when the value is absent.

Common situations: Implicit inputs keyed on optional context data (current directory, client version) where lookup silently yields nothing; mis-typed nil return of a typed nil pointer vs untyped nil interface.

Related errors


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