apache/beam · error

error decoding bool: %v

Error message

error decoding bool: %v

What it means

The exec coder's DecodeTo reads a single byte to decode a bool (0=false, 1=true). Any read error other than clean io.EOF is wrapped as 'error decoding bool'. io.EOF is passed through unchanged to signal a legitimate end of stream.

Source

Thrown at sdks/go/pkg/beam/core/runtime/exec/coder.go:363

	} else {
		_, err = ioutilx.WriteUnsafe(w, []byte{0})
	}
	if err != nil {
		return fmt.Errorf("error encoding bool: %v", err)
	}
	return nil
}

type boolDecoder struct{}

func (*boolDecoder) DecodeTo(r io.Reader, fv *FullValue) error {
	// Encoding: false = 0, true = 1
	b := make([]byte, 1)
	if err := ioutilx.ReadNBufUnsafe(r, b); err != nil {
		if err == io.EOF {
			return err
		}
		return fmt.Errorf("error decoding bool: %v", err)
	}
	switch b[0] {
	case 0:
		*fv = FullValue{Elm: false}
		return nil
	case 1:
		*fv = FullValue{Elm: true}
		return nil
	}
	return fmt.Errorf("error decoding bool: received invalid value %v", b)
}

func (d *boolDecoder) Decode(r io.Reader) (*FullValue, error) {
	fv := &FullValue{}
	if err := d.DecodeTo(r, fv); err != nil {
		return nil, err
	}
	return fv, nil

View on GitHub (pinned to 12126d8942)

Solutions

  1. Distinguish io.EOF (expected end of stream) from the wrapped error (real corruption/IO failure) with errors.Is.
  2. Verify the encoder wrote complete records; a truncated record often precedes this error.
  3. Check transport health (network, pipes) between the writing and reading stages.
  4. Regenerate or re-fetch the corrupted input data.

Example fix

// before: treating all errors the same
err := dec.DecodeTo(r, fv)
// after: distinguish EOF from corruption
if err := dec.DecodeTo(r, fv); err != nil && !errors.Is(err, io.EOF) {
    return fmt.Errorf("record corrupted: %w", errors.Unwrap(err))
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Frame records with lengths so readers never do partial reads mid-bool.

Type guard

func isEOF(err error) bool { return errors.Is(err, io.EOF) }

Try / catch

err := dec.DecodeTo(r, fv)
if err != nil {
    if errors.Is(err, io.EOF) { return io.EOF }
    if strings.Contains(err.Error(), "error decoding bool") { return ErrCorruptRecord }
    return err
}

Prevention

When it happens

Trigger: Decoding a bool from a stream where the read fails mid-byte: connection reset, corrupted reader, or an I/O error other than EOF. A clean EOF (no bytes at all) returns io.EOF instead.

Common situations: Truncated data channel between pipeline stages; reading past a partially written record so a partial read error surfaces; broken network transport during shuffle.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/52b0a6a16c702869. Report an issue: GitHub.