bytebase/bytebase · error

empty project filter

Error message

empty project filter

What it means

ListSavedQueries refuses to run when the FindSavedQueryMessage carries no project scope: both ProjectIDs is empty and Workspace is empty. Saved queries are always listed within a project scope (or explicitly workspace-wide), so an unscoped call would scan across projects, which the store deliberately forbids. It is a guard against a caller bug, not a data problem.

Source

Thrown at backend/store/saved_query.go:122

	sheets, err := s.ListSavedQueries(ctx, find)
	if err != nil {
		return nil, err
	}
	if len(sheets) == 0 {
		return nil, nil
	}
	if len(sheets) > 1 {
		return nil, errors.Errorf("expected 1 sheet, got %d", len(sheets))
	}
	sheet := sheets[0]

	return sheet, nil
}

// ListSavedQueries returns a list of sheets.
func (s *Store) ListSavedQueries(ctx context.Context, find *FindSavedQueryMessage) ([]*SavedQueryMessage, error) {
	if len(find.ProjectIDs) == 0 && find.Workspace == "" {
		return nil, errors.Errorf("empty project filter")
	}
	statementField := fmt.Sprintf("LEFT(saved_query.statement, %d)", common.MaxSheetSize)
	if find.LoadFull {
		statementField = "saved_query.statement"
	}

	q := qb.Q().Space(fmt.Sprintf(`
		SELECT
			saved_query.resource_id,
			saved_query.creator,
			saved_query.created_at,
			saved_query.updated_at,
			saved_query.project,
			saved_query.payload,
			saved_query.folder,
			saved_query.name,
			saved_query.bindings,
			%s,

View on GitHub (pinned to 1870550677)

Solutions

  1. Set find.ProjectIDs to the project(s) extracted from the API request parent before calling
  2. Set find.Workspace (e.g. to a workspace-wide marker) if the caller genuinely intends a cross-project listing
  3. Add a unit test asserting every caller of ListSavedQueries sets at least one of ProjectIDs/Workspace

Example fix

// before
sheets, err := store.ListSavedQueries(ctx, &store.FindSavedQueryMessage{})
// after
sheets, err := store.ListSavedQueries(ctx, &store.FindSavedQueryMessage{ProjectIDs: []string{projectID}})
Defensive patterns

Strategy: validation

Validate before calling

func validateFind(f *store.FindSavedQueryMessage) error {
	if len(f.ProjectIDs) == 0 && f.Workspace == "" {
		return errors.New("ListSavedQueries requires ProjectIDs or Workspace")
	}
	return nil
}

Type guard

func hasScope(f *store.FindSavedQueryMessage) bool { return len(f.ProjectIDs) > 0 || f.Workspace != "" }

Prevention

When it happens

Trigger: Calling ListSavedQueries with &FindSavedQueryMessage{} (no ProjectIDs, no Workspace); SearchSavedQueries or GetSavedQuery built a find message without setting ProjectIDs from the request's parent project, and without Workspace set.

Common situations: A service handler forgets to extract the project from the request parent (projects/{project}) before constructing FindSavedQueryMessage; a new caller lists all queries across projects assuming the store applies its own scoping; a refactor drops the Workspace flag for admin/workspace-wide listing while ProjectIDs remains nil.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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