bytebase/bytebase · error

failed to create pending task runs

Error message

failed to create pending task runs

What it means

The batch INSERT of pending task runs failed when executed inside the transaction (tx.ExecContext), and the store wraps the driver error as "failed to create pending task runs". The transaction is not committed, so no task_run rows are persisted. The underlying PostgreSQL error (constraint violation, FK failure, connection issue) is attached as the cause.

Source

Thrown at backend/store/task_run.go:497

			candidates.project,
			candidates.task_id,
			candidates.run_at,
			COALESCE((SELECT MAX(attempt) + 1 FROM task_run WHERE task_run.task_id = candidates.task_id AND task_run.project = candidates.project), 0),
			?,
			?
		FROM candidates
		ON CONFLICT (project, task_id, attempt) DO NOTHING
	`, projects, taskUIDs, runAts, baseID,
		storepb.TaskRun_PENDING.String(), storepb.TaskRun_AVAILABLE.String(), storepb.TaskRun_RUNNING.String(), storepb.TaskRun_DONE.String(),
		creatorPtr, storepb.TaskRun_PENDING.String(), payloadStr)

	query, args, err := q.ToSQL()
	if err != nil {
		return errors.Wrapf(err, "failed to build sql")
	}

	if _, err := tx.ExecContext(ctx, query, args...); err != nil {
		return errors.Wrapf(err, "failed to create pending task runs")
	}

	if err := tx.Commit(); err != nil {
		return errors.Wrapf(err, "failed to commit tx")
	}

	return nil
}

func (s *Store) listTaskRunCreationInstances(ctx context.Context, projects []string, taskUIDs []int64) ([]string, error) {
	q := qb.Q().Space(`
		SELECT DISTINCT task.instance
		FROM (
			SELECT
				unnest(CAST(? AS TEXT[])) AS project,
				unnest(CAST(? AS BIGINT[])) AS task_id
		) requested_tasks
		JOIN task ON task.project = requested_tasks.project AND task.id = requested_tasks.task_id

View on GitHub (pinned to 1870550677)

Solutions

  1. Read the wrapped driver error in the log — it names the exact constraint, FK, or connection failure
  2. Confirm all (project, task_id) pairs passed in still exist and are not skipped/archived
  3. Check metadata database health (PG_URL connectivity, migrations up to date)
  4. Retry the operation — the transaction rolled back atomically so state is clean
  5. Add ON CONFLICT coverage or pre-checks if id-base allocation races with concurrent creators

Example fix

// before: fire-and-forget scheduling
if err := store.CreatePendingTaskRuns(ctx, projects, uids, runAts); err != nil {
	return err
}
// after: pre-validate tasks exist before scheduling
if err := ensureTasksActive(ctx, store, projects, uids); err != nil {
	return errors.Wrap(err, "cannot schedule task runs")
}
if err := store.CreatePendingTaskRuns(ctx, projects, uids, runAts); err != nil {
	return errors.Wrap(err, "cannot schedule task runs")
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check tasks exist and are not skipped
for i := range taskUIDs {
	if _, err := store.GetTask(ctx, projects[i], taskUIDs[i]); err != nil {
		return errors.Wrapf(err, "task %d/%s does not exist", taskUIDs[i], projects[i])
	}
}

Try / catch

if _, err := tx.ExecContext(ctx, query, args...); err != nil {
	tx.Rollback()
	return errors.Wrapf(err, "failed to create pending task runs")
}

Prevention

When it happens

Trigger: Executing the batch INSERT at task_run.go:486 with a task_id/project that does not exist in the task table (FK violation); payload JSON rejected by the payload column; database unreachable or statement timeout; unique conflict other than the ON CONFLICT (project, task_id, attempt) case handled by DO NOTHING (e.g. id conflicts).

Common situations: Scheduling task runs for an archived instance whose task rows were removed concurrently; metadata DB under connectivity trouble during rollout creation; passing a payload string that violates a JSONB check; running against a schema version older than the code expects (missing columns).

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/52ed60a556be88b5. Report an issue: GitHub.