pulumi/pulumi · error

decoding event: %w

Error message

decoding event: %w

What it means

runChangesOnly decodes a JSONL stream of EngineEvents; a line that is valid-length but not a valid EngineEvent JSON causes dec.Decode to fail with something other than io.EOF, which is wrapped as "decoding event". The tool treats malformed input as fatal rather than skipping it.

Source

Thrown at pkg/cmd/pulumi/events/changes_only.go:38

	"fmt"
	"io"

	"github.com/pulumi/pulumi/sdk/v3/go/common/apitype"
)

// runChangesOnly reads a JSONL engine event stream from in, applies the `--changes-only` filter
// to each event, and writes the surviving events back as JSONL to out. Decoding errors are
// surfaced to the caller so that malformed input fails fast rather than silently dropping events.
func runChangesOnly(in io.Reader, out io.Writer) error {
	dec := json.NewDecoder(in)
	enc := json.NewEncoder(out)
	for {
		var evt apitype.EngineEvent
		if err := dec.Decode(&evt); err != nil {
			if errors.Is(err, io.EOF) {
				return nil
			}
			return fmt.Errorf("decoding event: %w", err)
		}
		filtered := filterChangesOnly(evt)
		if filtered == nil {
			continue
		}
		if err := enc.Encode(filtered); err != nil {
			return fmt.Errorf("encoding event: %w", err)
		}
	}
}

// filterChangesOnly applies the `--changes-only` transform to a single engine event, returning nil
// if the event should be dropped from the stream or a freshly-constructed, filtered copy otherwise.
//
// Rules:
//
//   - Non-resource events (stdout, diagnostic, prelude, summary, policy, progress, cancel, ...)
//     are passed through unchanged — they carry context the consumer may care about regardless of

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Inspect the offending line and repair/remove the malformed JSON in the stream
  2. Regenerate the event log from the source stack/operation
  3. Ensure both producer and consumer use compatible CLI versions with the same EngineEvent schema
  4. Sanitize the file (strip binary/partial lines) before running the filter

Example fix

// before (shell)
cat events.jsonl | pulumi events changes-only   # line 42 truncated
// after (shell)
grep -v '^$' events.jsonl | jq -c . >/dev/null && cat events.jsonl | pulumi events changes-only
Defensive patterns

Strategy: validation

Validate before calling

jq -c . events.jsonl >/dev/null || { echo "malformed JSONL input"; exit 1; }

Try / catch

if err := run(...); err != nil {
	if strings.Contains(err.Error(), "decoding event:") {
		fmt.Fprintf(os.Stderr, "inspect event log for corrupt/truncated lines: %v\n", err)
	}
}

Prevention

When it happens

Trigger: Piping `pulumi stack export`-style or event logs containing truncated/corrupt JSONL lines, wrong schema versions, or binary/rotated log content into the changes-only filter.

Common situations: Log files truncated mid-line by rotation; concatenating event logs from different CLI versions; piping output of a non-event command; partial downloads.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/5d70db8c2881fae4. Report an issue: GitHub.