go-delve/delve · error

can not slice %q

Error message

can not slice %q

What it means

Delve's expression evaluator (pkg/proc/eval.go) throws this when a slice expression x[low:high] is applied to a value of kind Slice, Array, or String whose base address (xev.Base) is 0. A zero base means the value has no backing memory — typically because it is nil or its storage could not be located. Delve refuses to fabricate an empty slice from a nonexistent base.

Source

Thrown at pkg/proc/eval.go:2273

		high, err = stack.pop().asInt()
		if err != nil {
			stack.err = err
			return
		}
	}
	xev := stack.pop()
	if xev.Unreadable != nil {
		stack.err = xev.Unreadable
		return
	}
	if !op.HasHigh {
		high = xev.Len
	}

	switch xev.Kind {
	case reflect.Slice, reflect.Array, reflect.String:
		if xev.Base == 0 {
			stack.err = fmt.Errorf("can not slice %q", astutil.ExprToString(op.Node.X))
			return
		}
		stack.pushErr(xev.reslice(low, high, op.TrustLen))
		return
	case reflect.Map:
		if op.Node.High != nil {
			stack.err = errors.New("second slice argument must be empty for maps")
			return
		}
		xev.mapSkip += int(low)
		xev.mapIterator(0) // reads map length
		if int64(xev.mapSkip) >= xev.Len {
			stack.err = errors.New("map index out of bounds")
			return
		}
		stack.push(xev)
		return
	case reflect.Ptr:

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Check the sliced variable with `print s` first; if it is nil or unreadable, fix the program state or step past the allocation point before slicing.
  2. Use `print s` with no slice bounds instead of slicing, to see the current state of the value.
  3. If the variable is genuinely allocated, avoid optimized builds (`-gcflags='all=-N -l'` via `dlv debug`/`dlv exec`) so Delve can read the slice header from memory.
  4. Re-enter the slice expression after the code path that assigns the slice has executed.

Example fix

// before (at dlv prompt, s is a nil slice)
(s) print s[0:2]
can not slice "s[0:2]"

// after: check and allocate first, then slice
(dlv) print s      // nil -> step until allocated
(dlv) print s[0:2] // works once s points at real memory
Defensive patterns

Strategy: validation

Validate before calling

// At the dlv prompt, before slicing:
(dlv) print s           // confirm non-nil and readable
// In program code:
if s != nil && len(s) >= 2 { use(s[1:2]) }

Type guard

func sliceable(v interface{}) bool {
    switch t := v.(type) {
    case []int, []string, string, []byte:
        _ = t
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Evaluating a slice expression in the debugger (CLI `print`, rpc2 Eval/Command, DAP evaluate) on a variable of slice/array/string type whose underlying data pointer is nil or whose Base could not be computed — e.g. `s[1:2]` where `s` is a nil slice, or slicing a string optimized into a register with no addressable backing store.

Common situations: Inspecting a slice field that was never initialized (nil slice), stepping through code before a slice is allocated, or slicing a variable the compiler kept in registers after inlining/optimization so Delve cannot resolve its data pointer.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/35c3bd6d204eeb9d. Report an issue: GitHub.