{"record":{"id":"f40540c5daa5285d","repo":"temporalio/temporal","slug":"s-is-not-a-valid-timestamp-w","errorCode":null,"errorMessage":"%s is not a valid timestamp: %w","messagePattern":"(.+?) is not a valid timestamp: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/frontend/workflow_handler.go","lineNumber":7038,"sourceCode":"\t\t\tif err := d.CheckValid(); err != nil {\n\t\t\t\treturn fmt.Errorf(\"phase is not a valid duration: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateScheduleTimestamps(spec *schedulepb.ScheduleSpec) error {\n\tif err := validateTimestamp(spec.GetStartTime(), \"start time\"); err != nil {\n\t\treturn err\n\t}\n\treturn validateTimestamp(spec.GetEndTime(), \"end time\")\n}\n\nfunc validateTimestamp(value *timestamppb.Timestamp, field string) error {\n\tif value != nil {\n\t\tif err := value.CheckValid(); err != nil {\n\t\t\treturn fmt.Errorf(\"%s is not a valid timestamp: %w\", field, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc validateScheduleRemainingActions(schedule *schedulepb.Schedule) error {\n\tif schedule.GetState().GetRemainingActions() < 0 {\n\t\treturn errors.New(\"remaining actions cannot be negative\")\n\t}\n\treturn nil\n}\n\nfunc validateScheduleOverlapPolicy(policy enumspb.ScheduleOverlapPolicy, field string) error {\n\tif _, ok := enumspb.ScheduleOverlapPolicy_name[int32(policy)]; !ok {\n\t\treturn fmt.Errorf(\"%s has unsupported overlap policy %v\", field, policy)\n\t}\n\treturn nil\n}","sourceCodeStart":7020,"sourceCodeEnd":7056,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/frontend/workflow_handler.go#L7020-L7056","documentation":"Generic helper validateTimestamp wraps timestamppb.Timestamp.CheckValid() failures with the field name (e.g. 'start time', 'end time'). A timestamp fails CheckValid when it is nil-valued fields, out-of-range seconds/nanos, or otherwise not a valid RFC3339-representable time.","triggerScenarios":"Schedule API calls passing a ScheduleSpec with StartTime/EndTime (or other validated timestamps) built from malformed or out-of-range protobuf Timestamp values.","commonSituations":"Converting from milliseconds-since-epoch incorrectly; overflow when converting int64 seconds; passing a zero timestamp from an uninitialized struct.","solutions":["Use timestamppb.New(t) from a valid time.Time","Check ts.CheckValid() or timestamppb.Timestamp IsValid before the call","Verify epoch conversion math (seconds vs milliseconds) when hand-building timestamps"],"exampleFix":"// before\nts := &timestamppb.Timestamp{Seconds: 99999999999999999999}\n// after\nts := timestamppb.New(time.Now().UTC().Add(24 * time.Hour))","handlingStrategy":"validation","validationCode":"if ts != nil && ts.CheckValid() != nil { return fmt.Errorf(\"invalid timestamp for %s\", field) }","typeGuard":"func validTimestamp(ts *timestamppb.Timestamp) bool { return ts == nil || ts.IsValid() }","tryCatchPattern":"if err := validateTimestamp(spec.GetEndTime(), \"end time\"); err != nil { return serviceerror.NewInvalidArgument(err.Error()) }","preventionTips":["Construct timestamps with timestamppb.New(time.Time)","Call ts.CheckValid() before sending requests","Audit epoch conversions for seconds-vs-millis mistakes"],"tags":["timestamp","protobuf","schedule","validation","go"],"backgroundTag":"invalid-timestamp","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}