juicedata/juicefs · error

handler not set

Error message

handler not set

What it means

sliceIterator.Iterate in pkg/vfs/fill.go requires a non-nil sliceHandler callback to receive each slice and its parts as it walks the chunk slices of an inode. If the caller passes nil, the iterator refuses to start because there would be nowhere to deliver results, returning "handler not set". It is a pure programmer-error guard, not a runtime/environment failure.

Source

Thrown at pkg/vfs/fill.go:442

	}

	var parts []chunk.Range
	for _, r := range iter.ranges {
		start := max(r.Start, sliceStart)
		end := min(r.End, sliceStart+uint64(s.Len))
		if start < end {
			parts = append(parts, chunk.Range{
				Off: s.Off + uint32(start-sliceStart),
				Len: uint32(end - start),
			})
		}
	}
	return s, parts
}

func (iter *sliceIterator) Iterate(handler sliceHandler, concurrent chan token) error {
	if handler == nil {
		return fmt.Errorf("handler not set")
	}
	var wg sync.WaitGroup
	for iter.hasNext() {
		s, parts := iter.next()
		if len(parts) == 0 {
			continue
		}
		var bytes uint64
		for _, p := range parts {
			bytes += uint64(p.Len)
		}
		atomic.AddUint64(&iter.stat.SliceCount, 1)
		atomic.AddUint64(&iter.stat.TotalBytes, bytes)

		select {
		case concurrent <- token{}:
			wg.Add(1)
			go func() {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Pass a non-nil sliceHandler implementation to Iterate.
  2. If the handler is legitimately optional, return early before calling Iterate instead of passing nil.
  3. Check the variable that supplies the handler for a typo/uninitialized field assignment.

Example fix

// before
err := iter.Iterate(nil, concurrent)
// after
if handler == nil {
    return errors.New("no slice handler provided")
}
err := iter.Iterate(handler, concurrent)
Defensive patterns

Strategy: validation

Validate before calling

if handler == nil {
    return errors.New("slice handler must be provided")
}
err := iter.Iterate(handler, concurrent)

Type guard

func handlerSet(h sliceHandler) bool { return h != nil }

Try / catch

if err := iter.Iterate(handler, concurrent); err != nil {
    if strings.Contains(err.Error(), "handler not set") { /* fix caller */ }
    return err
}

Prevention

When it happens

Trigger: Calling Iterate(nil, concurrent) on a *sliceIterator, e.g. when wrapping fillCache/fill chunk iteration and forwarding a nil callback, or when a struct field holding the handler was never initialized before the iterate call.

Common situations: Refactoring the cache-fill path where the handler is conditionally assigned; calling Iterate from a helper that takes an optional handler parameter; wiring VFS internal callbacks asynchronously so the field is still nil at call time.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/621bd8fb0530abf5. Report an issue: GitHub.