{"record":{"id":"7eddb07626f064a1","repo":"GoogleContainerTools/skaffold","slug":"marshalling-event-w-7eddb0","errorCode":null,"errorMessage":"marshalling event: %w","messagePattern":"marshalling event: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/event/v2/event.go","lineNumber":329,"sourceCode":"\n// SaveEventsToFile saves the current event log to the filepath provided\nfunc SaveEventsToFile(fp string) error {\n\thandler.logLock.Lock()\n\t// Ensure that the filepath provided has the directories available when attemping to save the file.\n\tdir := filepath.Dir(fp)\n\tif err := os.MkdirAll(dir, 0700); err != nil {\n\t\treturn fmt.Errorf(\"unable to create directory %q: %w\", dir, err)\n\t}\n\tf, err := os.OpenFile(fp, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"opening %s: %w\", fp, err)\n\t}\n\tdefer f.Close()\n\tmarshaller := jsonpb.Marshaler{}\n\tfor _, ev := range handler.eventLog {\n\t\tcontents := bytes.NewBuffer([]byte{})\n\t\tif err := marshaller.Marshal(contents, ev); err != nil {\n\t\t\treturn fmt.Errorf(\"marshalling event: %w\", err)\n\t\t}\n\t\tif _, err := f.WriteString(contents.String() + \"\\n\"); err != nil {\n\t\t\treturn fmt.Errorf(\"writing string: %w\", err)\n\t\t}\n\t}\n\thandler.logLock.Unlock()\n\treturn nil\n}\n\n// SaveLastLog writes the output from the previous run to the specified filepath\nfunc SaveLastLog(fp string) error {\n\thandler.logLock.Lock()\n\tdefer handler.logLock.Unlock()\n\n\t// Create file to write logs to\n\tfp, err := lastLogFile(fp)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"getting last log file %w\", err)","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/event/v2/event.go#L311-L347","documentation":"SaveEventsToFile iterates the in-memory event log and serializes each event to JSON using golang/protobuf jsonpb.Marshaler before writing it to the file. This error wraps any failure from jsonpb Marshal when converting a proto event message to JSON, e.g. an event message that violates proto3 JSON mapping rules. It means one entry in handler.eventLog could not be serialized, so saving the event file aborts.","triggerScenarios":"Calling SaveEventsToFile when a recorded event in handler.eventLog cannot be marshaled by jsonpb.Marshaler{} — typically because the registered event's oneof payload is nil/invalid, an enum value is out of range, or a custom proto type fails its JSON mapping.","commonSituations":"Running TestSaveEventsToFile or a real session where a malformed/internally-inconsistent event was recorded; version skew where event protos were built with mismatched generated code; events enqueued with unset oneof cases.","solutions":["Inspect handler.eventLog for the offending event and fix the code that recorded it so the proto message is fully valid.","Regenerate proto code so generated Go types and the jsonpb library versions match.","Skip-and-log unmarshalable events instead of aborting the whole save, then re-run to see which event type is at fault."],"exampleFix":"// before\nif err := marshaller.Marshal(contents, ev); err != nil {\n    return fmt.Errorf(\"marshalling event: %w\", err)\n}\n// after\nif err := marshaller.Marshal(contents, ev); err != nil {\n    log.Entry(context.TODO()).Warnf(\"skipping unmarshalable event %T: %v\", ev, err)\n    continue\n}","handlingStrategy":"try-catch","validationCode":"for _, ev := range handler.eventLog {\n    if ev == nil || ev.GetEvent() == nil {\n        return fmt.Errorf(\"invalid event in log at index %d\", i)\n    }\n}","typeGuard":"func isValidEvent(ev *proto.Event) bool {\n    return ev != nil && ev.GetEvent() != nil\n}","tryCatchPattern":"if err := event.SaveEventsToFile(path); err != nil {\n    if strings.Contains(err.Error(), \"marshalling event\") {\n        log.Warnf(\"event log contains unmarshalable entries: %v\", err)\n    } else {\n        return err\n    }\n}","preventionTips":["Only record fully initialized events onto handler.eventLog","Keep proto generated code and golang/protobuf versions in sync","Add a unit test that round-trips every registered event type through jsonpb"],"tags":["serialization","protobuf","json","events"],"backgroundTag":"proto-json-marshalling-failed","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}