hashicorp/nomad · error

'io.Reader' being decoded is nil

Error message

'io.Reader' being decoded is nil

What it means

KVBuilder.addReader decodes JSON from an io.Reader into the result map. This error is thrown immediately when the reader passed in is nil, before any JSON decoding is attempted. It is a defensive guard against wiring mistakes where no input source was configured.

Source

Thrown at command/var.go:282

	// Repeated keys will be converted into a slice
	if existingValue, ok := b.result[key]; ok {
		var sliceValue []any
		if err := mapstructure.WeakDecode(existingValue, &sliceValue); err != nil {
			return err
		}
		sliceValue = append(sliceValue, value)
		b.result[key] = sliceValue
		return nil
	}

	b.result[key] = value
	return nil
}

func (b *KVBuilder) addReader(r io.Reader) error {
	if r == nil {
		return fmt.Errorf("'io.Reader' being decoded is nil")
	}

	dec := json.NewDecoder(r)
	// While decoding JSON values, interpret the integer values as
	// `json.Number`s instead of `float64`.
	dec.UseNumber()

	return dec.Decode(&b.result)
}

// handleCASError provides consistent output for operations that result in a
// check-and-set error
func handleCASError(err error, c VarUI) (handled bool) {
	ui := c.GetConcurrentUI()
	if cErr, ok := errors.AsType[api.ErrCASConflict](err); ok {
		lastUpdate := ""
		if cErr.Conflict.ModifyIndex > 0 {
			lastUpdate = fmt.Sprintf(

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the reader passed to addReader (or KVBuilder.Stdin) is non-nil before the call
  2. Check the code path that produces the reader — a failed os.Open or unset field — and handle its error/zero value first
  3. Prefer the public Add API which pre-validates Stdin, rather than calling addReader directly

Example fix

// before
var r io.Reader // nil
b.addReader(r)
// after
if r == nil { r = strings.NewReader("{}") }
b.addReader(r)
Defensive patterns

Strategy: type-guard

Validate before calling

func nonNilReader(r io.Reader) io.Reader {
	if r == nil { return strings.NewReader("{}") }
	return r
}

Type guard

func isNilReader(r io.Reader) bool {
	if r == nil { return true }
	if v := reflect.ValueOf(r); v.Kind() == reflect.Ptr && v.IsNil() { return true }
	return false
}

Prevention

When it happens

Trigger: Calling KVBuilder.addReader(nil) directly, or reaching it via Add("-")/Add("key=@-") paths where the configured reader (b.Stdin or an opened file handle) ended up nil.

Common situations: Programmatic construction of KVBuilder with a nil Stdin; a helper that returns (io.Reader, error) and a nil reader being passed through unchecked; variable shadowing leaving the reader unset.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/298981d92cf94100. Report an issue: GitHub.