vitessio/vitess · error

removing from wrong List

Error message

removing from wrong List

What it means

list.List.Remove panics if the given element belongs to a different list (e.list != l). Elements carry a back-pointer to their owning list; removing an element from a list it was never inserted into (or already moved to another list) is a programming error. Use RemoveIfPresent when the element may already have been removed.

Source

Thrown at go/list/list.go:138

func (l *List[T]) move(e, at *Element[T]) {
	if e == at {
		return
	}
	e.prev.next = e.next
	e.next.prev = e.prev

	e.prev = at
	e.next = at.next
	e.prev.next = e
	e.next.prev = e
}

// Remove removes e from l. The element must not be nil and must be an
// element of list l; Remove panics otherwise. Use RemoveIfPresent when the
// element may have been removed already.
func (l *List[T]) Remove(e *Element[T]) {
	if e.list != l {
		panic("removing from wrong List")
	}
	// if e.list == l, l must have been initialized when e was inserted
	// in l or l == nil (e is a zero Element) and l.remove will crash
	l.remove(e)
}

// RemoveIfPresent removes e from l if e is currently an element of list l
// and reports whether it did so. Unlike Remove, it is a no-op rather than a
// panic when e is not in l, which makes membership checks O(1) for callers
// that would otherwise have to scan the list before removing.
// The element must not be nil.
func (l *List[T]) RemoveIfPresent(e *Element[T]) bool {
	if e.list != l {
		return false
	}
	l.remove(e)
	return true
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Ensure the element was inserted into exactly this list instance before calling Remove.
  2. Switch to RemoveIfPresent if the element may already have been removed.
  3. Track ownership of elements so each element is only removed from the list it came from.

Example fix

// before
if cond {
    listA.Remove(elem) // elem actually lives in listB
}
// after
if cond && elem.List() == listA {
    listA.Remove(elem)
}
Defensive patterns

Strategy: type-guard

Validate before calling

if elem.list != mylist {
    return errors.New("element does not belong to this list")
}
mylist.Remove(elem)

Type guard

func belongsTo[T any](e *list.Element[T], l *list.List[T]) bool {
    return e != nil && e.List() == l
}

Try / catch

func safeRemove[T any](l *list.List[T], e *list.Element[T]) (ok bool) {
    defer func() {
        if r := recover(); r != nil {
            ok = false
        }
    }()
    if e.List() != l {
        return false
    }
    l.Remove(e)
    return true
}

Prevention

When it happens

Trigger: Calling l.Remove(e) where e was inserted into a different List, or where e is a zero-value Element that was never inserted, or where e was moved to another list.

Common situations: Managing multiple linked lists and mixing up which element came from which; removing the same element from two lists; retaining elements across list re-creation; copying an Element by value so its list pointer points at the original list.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/0290b1618806b3ac. Report an issue: GitHub.