bytebase/bytebase · error

task run %d not found in project %s

Error message

task run %d not found in project %s

What it means

UpdateTaskRunStartAt requires the task_run row identified by the full composite key (project, id). If the UPDATE affects zero rows, it reports 'task run %d not found in project %s' (backend/store/task_run.go:309-311). Task run IDs are allocated per project by nextProjectID, so the id alone is ambiguous — the project scope must match too.

Source

Thrown at backend/store/task_run.go:310

		SET started_at = now(), updated_at = now()
		WHERE id = ? AND project = ?
	`, taskRunID, projectID)

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

	result, err := s.GetDB().ExecContext(ctx, query, args...)
	if err != nil {
		return errors.Wrapf(err, "failed to update task run start at")
	}
	rowsAffected, err := result.RowsAffected()
	if err != nil {
		return errors.Wrapf(err, "failed to get affected task run count")
	}
	if rowsAffected == 0 {
		return errors.Errorf("task run %d not found in project %s", taskRunID, projectID)
	}
	return nil
}

// CreatePendingTaskRuns creates pending task runs.
// This operation is idempotent and safe for concurrent calls:
// - Excludes skipped tasks and tasks that already have active (PENDING/RUNNING/DONE) task runs
// - Uses ON CONFLICT DO NOTHING to handle race conditions where two requests try to create the same task run
// - The unique constraint on (task_id, attempt) ensures no duplicates
func (s *Store) CreatePendingTaskRuns(ctx context.Context, creator string, creates ...*TaskRunMessage) error {
	if len(creates) == 0 {
		return nil
	}
	projectID := creates[0].ProjectID
	for _, create := range creates[1:] {
		if create.ProjectID != projectID {
			return common.Errorf(common.Invalid, "all task runs in a batch must belong to the same project")
		}

View on GitHub (pinned to 1870550677)

Solutions

  1. Verify the task run exists with a query scoped by both project and id.
  2. Confirm the caller passes the correct projectID alongside the task run id.
  3. Handle the case where the run was already terminated — skip or log instead of treating as fatal.
  4. Check for cross-project ID confusion since ids are only unique per project.

Example fix

// before
if err := store.UpdateTaskRunStartAt(ctx, projectID, taskRunID); err != nil {
	return err
}
// after
err := store.UpdateTaskRunStartAt(ctx, projectID, taskRunID)
if err != nil && strings.Contains(err.Error(), "not found in project") {
	log.Warnf("task run %d/%s already gone; skipping", taskRunID, projectID)
	return nil
}
return err
Defensive patterns

Strategy: validation

Validate before calling

run, err := store.GetTaskRun(ctx, projectID, taskRunID)
if err != nil {
	return fmt.Errorf("task run %d/%s does not exist: %w", taskRunID, projectID, err)
}

Try / catch

if err := store.UpdateTaskRunStartAt(ctx, projectID, taskRunID); err != nil {
	if strings.Contains(err.Error(), "not found in project") {
		log.Warnf("run %d/%s vanished; skipping", taskRunID, projectID)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: Calling Store.UpdateTaskRunStartAt(ctx, projectID, taskRunID) where no task_run row has both that project and id: the run was deleted, the id belongs to a different project, or a mistyped/unpadded id was passed.

Common situations: The task run was already finished/purged before execution attempted to start it; a caller mixed up IDs across projects (per-project IDs collide, e.g. both projects have id 101); a typo in projectID.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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