dagger/dagger · error

encode persisted LLM variable: nil LLM variable

Error message

encode persisted LLM variable: nil LLM variable

What it means

LLMVariable.EncodePersistedObject refuses to encode a nil *LLMVariable receiver when persisting it as a cache/persisted object. Encoding a nil value would produce a meaningless payload that couldn't be decoded back, so it is rejected explicitly.

Source

Thrown at core/llm.go:2737

	Hash string `field:"true"`
}

var _ dagql.Typed = (*LLMVariable)(nil)
var _ dagql.PersistedObject = (*LLMVariable)(nil)
var _ dagql.PersistedObjectDecoder = (*LLMVariable)(nil)

func (v *LLMVariable) Type() *ast.Type {
	return &ast.Type{
		NamedType: "LLMVariable",
		NonNull:   true,
	}
}

func (v *LLMVariable) EncodePersistedObject(ctx context.Context, cache dagql.PersistedObjectCache) (dagql.PersistedObjectEncoding, error) {
	_ = ctx
	_ = cache
	if v == nil {
		return dagql.PersistedObjectEncoding{}, fmt.Errorf("encode persisted LLM variable: nil LLM variable")
	}
	return encodePersistedObjectPayload(v)
}

func (*LLMVariable) DecodePersistedObject(ctx context.Context, dag *dagql.Server, _ uint64, _ *dagql.ResultCall, payload json.RawMessage) (dagql.Typed, error) {
	_ = ctx
	_ = dag
	var v LLMVariable
	if err := json.Unmarshal(payload, &v); err != nil {
		return nil, fmt.Errorf("decode persisted LLM variable payload: %w", err)
	}
	return &v, nil
}

func (llm *LLM) TokenUsage(ctx context.Context, dag *dagql.Server) (*LLMTokenUsage, error) {
	var res LLMTokenUsage
	for _, msg := range llm.Messages {
		if msg.TokenUsage == nil {

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Ensure the LLMVariable is fully constructed before it reaches the persistence layer
  2. Guard callers with a nil check and skip persistence for nil variables
  3. Investigate why a nil variable entered the environment (uninitialized env binding)

Example fix

// before
var v *LLMVariable
enc, err := v.EncodePersistedObject(ctx, cache)
// after
if v == nil {
    return errors.New("no LLM variable to persist")
}
enc, err := v.EncodePersistedObject(ctx, cache)
Defensive patterns

Strategy: type-guard

Validate before calling

if v == nil {
    return errors.New("cannot persist nil LLM variable")
}

Type guard

func (v *LLMVariable) isPersistable() bool { return v != nil && v.Name != "" }

Prevention

When it happens

Trigger: Passing a nil *LLMVariable into the persisted-object encoding path, e.g. an LLM environment variable slot that was never populated but got scheduled for cache persistence.

Common situations: Programmatically built LLM environments where a variable pointer was left nil; reflection-driven code paths that don't check for nil before persisting.

Related errors


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