{"record":{"id":"5d70db8c2881fae4","repo":"pulumi/pulumi","slug":"decoding-event-w","errorCode":null,"errorMessage":"decoding event: %w","messagePattern":"decoding event: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cmd/pulumi/events/changes_only.go","lineNumber":38,"sourceCode":"\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/pulumi/pulumi/sdk/v3/go/common/apitype\"\n)\n\n// runChangesOnly reads a JSONL engine event stream from in, applies the `--changes-only` filter\n// to each event, and writes the surviving events back as JSONL to out. Decoding errors are\n// surfaced to the caller so that malformed input fails fast rather than silently dropping events.\nfunc runChangesOnly(in io.Reader, out io.Writer) error {\n\tdec := json.NewDecoder(in)\n\tenc := json.NewEncoder(out)\n\tfor {\n\t\tvar evt apitype.EngineEvent\n\t\tif err := dec.Decode(&evt); err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"decoding event: %w\", err)\n\t\t}\n\t\tfiltered := filterChangesOnly(evt)\n\t\tif filtered == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err := enc.Encode(filtered); err != nil {\n\t\t\treturn fmt.Errorf(\"encoding event: %w\", err)\n\t\t}\n\t}\n}\n\n// filterChangesOnly applies the `--changes-only` transform to a single engine event, returning nil\n// if the event should be dropped from the stream or a freshly-constructed, filtered copy otherwise.\n//\n// Rules:\n//\n//   - Non-resource events (stdout, diagnostic, prelude, summary, policy, progress, cancel, ...)\n//     are passed through unchanged — they carry context the consumer may care about regardless of","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/cmd/pulumi/events/changes_only.go#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"Log files truncated mid-line by rotation; concatenating event logs from different CLI versions; piping output of a non-event command; partial downloads.","solutions":["Inspect the offending line and repair/remove the malformed JSON in the stream","Regenerate the event log from the source stack/operation","Ensure both producer and consumer use compatible CLI versions with the same EngineEvent schema","Sanitize the file (strip binary/partial lines) before running the filter"],"exampleFix":"// before (shell)\ncat events.jsonl | pulumi events changes-only   # line 42 truncated\n// after (shell)\ngrep -v '^$' events.jsonl | jq -c . >/dev/null && cat events.jsonl | pulumi events changes-only","handlingStrategy":"validation","validationCode":"jq -c . events.jsonl >/dev/null || { echo \"malformed JSONL input\"; exit 1; }\n","typeGuard":null,"tryCatchPattern":"if err := run(...); err != nil {\n\tif strings.Contains(err.Error(), \"decoding event:\") {\n\t\tfmt.Fprintf(os.Stderr, \"inspect event log for corrupt/truncated lines: %v\\n\", err)\n\t}\n}","preventionTips":["Validate JSONL with jq before filtering","Avoid concatenating event logs across CLI versions","Protect log files from truncation during rotation"],"tags":["jsonl","events","parsing","stream"],"backgroundTag":"malformed-json-line","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}