bytebase/bytebase · error
cannot create rollout for a draft issue; submit it first
Error message
cannot create rollout for a draft issue; submit it first
What it means
Rollout creation guard (errDraftIssueNotSubmitted): the plan's issue is still a draft, and rollouts can only be created for submitted issues. Failing here prevents a rollout executing a plan nobody has finalized; detected via IsDraftIssueNotSubmittedError.
Source
Thrown at backend/api/v1/rollout_service.go:47
"github.com/bytebase/bytebase/backend/plugin/db"
parserbase "github.com/bytebase/bytebase/backend/plugin/parser/base"
"github.com/bytebase/bytebase/backend/store"
"github.com/bytebase/bytebase/backend/utils"
)
// RolloutService represents a service for managing rollout.
type RolloutService struct {
v1connect.UnimplementedRolloutServiceHandler
store *store.Store
dbFactory *dbfactory.DBFactory
bus *bus.Bus
webhookManager *webhook.Manager
iamManager *iam.Manager
}
var (
errStaleRolloutApproval = errors.New("cannot create rollout because issue approval is stale")
errDraftIssueNotSubmitted = errors.New("cannot create rollout for a draft issue; submit it first")
)
// IsStaleRolloutApprovalError reports whether rollout creation lost the approval-version race.
func IsStaleRolloutApprovalError(err error) bool {
return errors.Is(err, errStaleRolloutApproval)
}
// IsDraftIssueNotSubmittedError reports whether rollout creation was blocked by a draft issue.
func IsDraftIssueNotSubmittedError(err error) bool {
return errors.Is(err, errDraftIssueNotSubmitted)
}
// NewRolloutService returns a rollout service instance.
func NewRolloutService(store *store.Store, dbFactory *dbfactory.DBFactory, bus *bus.Bus, webhookManager *webhook.Manager, iamManager *iam.Manager) *RolloutService {
return &RolloutService{
store: store,
dbFactory: dbFactory,
bus: bus,View on GitHub (pinned to 1870550677)
Solutions
- Submit the issue first (via the issue service) and then call CreateRollout
- Guard callers with IsDraftIssueNotSubmittedError and prompt the user to submit
- Check the issue's state before attempting rollout creation
Example fix
// before
_, err := rolloutClient.CreateRollout(ctx, req)
// after
if err := issueClient.SubmitIssue(ctx, issueReq); err != nil {
return err
}
_, err := rolloutClient.CreateRollout(ctx, req) Defensive patterns
Strategy: try-catch
Validate before calling
if issue.GetState() == v1pb.Issue_STATE_UNSPECIFIED /* or draft marker */ {
return errors.New("submit the issue before creating a rollout")
} Try / catch
_, err := rolloutClient.CreateRollout(ctx, req)
if err != nil {
if v1.IsDraftIssueNotSubmittedError(err) {
return fmt.Errorf("submit the issue first, then retry the rollout")
}
return err
} Prevention
- Make issue submission a mandatory step in automation pipelines before rollout
- Check issue state in the UI/API flow before exposing the rollout action
When it happens
Trigger: Calling CreateRollout (or CreateRolloutAndPendingTasks) with a plan whose issue has not been submitted — e.g. a persisted draft issue passed directly to rollout creation.
Common situations: Automation pipelines creating issues programmatically and immediately rolling out without the submit step; UI state drift where a user triggers rollout on a draft; retries against issues that were reverted to draft.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- plan has rollout
- cannot create rollout because issue approval is stale
- failed to refresh issue
- failed to check if approval is approved
- failed to complete role grant
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/cacdb1a5a9c8ffe0.
Report an issue: GitHub.