{"record":{"id":"6137c3f7babbd6b8","repo":"temporalio/temporal","slug":"remaining-actions-cannot-be-negative","errorCode":null,"errorMessage":"remaining actions cannot be negative","messagePattern":"remaining actions cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/frontend/workflow_handler.go","lineNumber":7046,"sourceCode":"func 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}\n\nfunc (wh *WorkflowHandler) validateScheduleOverlapPolicies(\n\tschedule *schedulepb.Schedule,\n\tpatch *schedulepb.SchedulePatch,\n\tnamespaceName string,\n) error {\n\tif schedule != nil {\n\t\tif err := validateScheduleOverlapPolicy(schedule.GetPolicies().GetOverlapPolicy(), \"schedule policies\"); err != nil {","sourceCodeStart":7028,"sourceCodeEnd":7064,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/frontend/workflow_handler.go#L7028-L7064","documentation":"Validation error from validateScheduleRemainingActions: a Schedule's state reports a negative RemainingActions count. RemainingActions tracks how many more actions the schedule may take (for limited schedules) and must be >= 0; a negative value indicates corrupted schedule state.","triggerScenarios":"Validate/Update or schedule-related API calls that supply or persist a schedule whose State.RemainingActions is negative, e.g. via UpdateSchedule with crafted state, or restored/corrupted schedule records.","commonSituations":"Importing schedule state from backups or other clusters, off-by-one bugs when decrementing remaining actions in old versions, or hand-crafted workflow update requests.","solutions":["Inspect the schedule state and set RemainingActions to a correct non-negative value (0 for exhausted, unset/unlimited appropriately)","If state is corrupted, update the schedule via UpdateSchedule with correct limits rather than importing raw state","Check the version that produced the schedule for known decrement bugs and upgrade"],"exampleFix":"// before (crafted schedule state)\nschedule.State.RemainingActions = -1\n// after\nschedule.State.RemainingActions = 0 // or omit for unlimited","handlingStrategy":"validation","validationCode":"if schedule.GetState().GetRemainingActions() < 0 {\n    return errors.New(\"remaining actions must be >= 0\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never import or hand-craft schedule state with negative counters","Validate schedule updates client-side before calling UpdateSchedule","Keep the server version current to benefit from schedule state bug fixes"],"tags":["schedule","validation","frontend-api"],"backgroundTag":"schedule-state-validation-failed","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}