{"record":{"id":"005c0d11f42d4fb4","repo":"temporalio/temporal","slug":"invalid-schedule-s","errorCode":null,"errorMessage":"invalid schedule: %s","messagePattern":"invalid schedule: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/worker/scheduler/workflow.go","lineNumber":1170,"sourceCode":"func (s *scheduler) handleDescribeQuery() (*schedulespb.DescribeResponse, error) {\n\t// this is a query handler, don't modify s.Info directly\n\tinfoCopy := common.CloneProto(s.Info)\n\tinfoCopy.FutureActionTimes = s.getFutureActionTimes(false, s.tweakables.FutureActionCount)\n\tinfoCopy.BufferSize = int64(len(s.State.BufferedStarts))\n\n\treturn &schedulespb.DescribeResponse{\n\t\tSchedule:      s.Schedule,\n\t\tInfo:          infoCopy,\n\t\tConflictToken: s.State.ConflictToken,\n\t}, nil\n}\n\nfunc (s *scheduler) handleListMatchingTimesQuery(req *workflowservice.ListScheduleMatchingTimesRequest) (*workflowservice.ListScheduleMatchingTimesResponse, error) {\n\tif req == nil || req.StartTime == nil || req.EndTime == nil {\n\t\treturn nil, errors.New(\"missing or invalid query\")\n\t}\n\tif s.cspec == nil {\n\t\treturn nil, fmt.Errorf(\"invalid schedule: %s\", s.Info.InvalidScheduleError)\n\t}\n\n\tvar out []*timestamppb.Timestamp\n\tt1 := timestamp.TimeValue(req.StartTime)\n\tfor range maxListMatchingTimesCount {\n\t\t// don't need to call GetNextTime in SideEffect because this is just a query\n\t\tres, err := s.cspec.GetNextTime(s.jitterSeed(), t1)\n\t\tif err != nil {\n\t\t\t// An over-excluded spec won't resolve until it's edited, so return a\n\t\t\t// non-retryable code: retrying would just re-burn the compute bound each call.\n\t\t\treturn nil, ErrScheduleSpecLimitHit\n\t\t}\n\t\tt1 = res.Next\n\t\tif t1.IsZero() || t1.After(timestamp.TimeValue(req.EndTime)) {\n\t\t\tbreak\n\t\t}\n\t\tout = append(out, timestamppb.New(t1))\n\t}","sourceCodeStart":1152,"sourceCodeEnd":1188,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/worker/scheduler/workflow.go#L1152-L1188","documentation":"handleListMatchingTimesQuery answers ListScheduleMatchingTimes queries by iterating the scheduler's parsed calendar spec (s.cspec). If cspec is nil — the schedule workflow started before the spec was loaded or the workflow state is corrupt — the query cannot be answered and the workflow's InvalidScheduleError is surfaced.","triggerScenarios":"Sending a ListScheduleMatchingTimes query to a schedule workflow whose cspec is nil, typically right after workflow start before initialization completes, or when the schedule was created invalid/legacy state.","commonSituations":"Querying a schedule immediately after Describe/Create; schedule workflows recovered from old versions; s.Info.InvalidScheduleError set by an earlier failed spec parse.","solutions":["Retry the query after the schedule workflow has fully started (brief delay)","Check the schedule with DescribeSchedule and fix the invalid schedule spec reported in InvalidScheduleError","Delete and recreate the schedule with a valid spec if state is unrecoverable"],"exampleFix":"// before\nresp, err := frontendClient.ListScheduleMatchingTimes(ctx, req) // immediately after CreateSchedule\n// after\nschedule.Handle(ctx, client, \"sched-id\", func(s schedule.ScheduleClientHandle) error {\n    return require.Eventually-style polling until DescribeSchedule succeeds\n})","handlingStrategy":"try-catch","validationCode":"// check schedule validity first\n_, err := frontendClient.DescribeSchedule(ctx, &workflowservice.DescribeScheduleRequest{ScheduleId: id})\nif err != nil { return err } // then inspect Info.InvalidSchedule before querying","typeGuard":null,"tryCatchPattern":"resp, err := client.ListScheduleMatchingTimes(ctx, req)\nvar svcErr *serviceerror.InvalidArgument\nif errors.As(err, &svcErr) && strings.Contains(svcErr.Message, \"invalid schedule\") {\n    // wait for workflow start / inspect InvalidScheduleError via DescribeSchedule\n}","preventionTips":["Don't query ListScheduleMatchingTimes immediately after CreateSchedule; retry briefly","Inspect DescribeSchedule's invalid-schedule state before issuing matching-times queries","Recreate schedules from valid specs after failed server migrations"],"tags":["scheduler","query","workflow","go"],"backgroundTag":"invalid-schedule-state","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}