bytebase/bytebase · error

database is required

Error message

database is required

What it means

The MCP `getSchema` tool resolves schema metadata for a specific database, so `input.Database` must be set. `database is required` is returned immediately when it is empty, before resolving the include level or checking permissions. TestGetSchema_MissingDatabase exercises exactly this path.

Source

Thrown at backend/api/mcp/tool_schema.go:235

- Write a query: get_schema(database="employee", include="columns") → all tables with columns

**Notes:**
- Metadata is auto-synced on access. The first call to a stale database may take longer.
- For databases with many tables, columns/details modes return up to 200 tables PER SCHEMA.
  Use schema= or table= to narrow further.
- Column masking metadata is only returned when table= is set.
- Requires bb.databases.getSchema permission.`

func (s *Server) registerSchemaTool() {
	mcp.AddTool(s.mcpServer, &mcp.Tool{
		Name:        "get_schema",
		Description: getSchemaDescription,
	}, s.handleGetSchema)
}

func (s *Server) handleGetSchema(ctx context.Context, req *mcp.CallToolRequest, input SchemaInput) (*mcp.CallToolResult, any, error) {
	if input.Database == "" {
		return nil, nil, errors.New("database is required")
	}

	include, err := resolveIncludeLevel(input)
	if err != nil {
		return nil, nil, err
	}

	resolved, resolveResult := s.resolveTarget(ctx, req, input.Database, input.Instance, input.Project)
	if resolveResult != nil {
		return resolveResult, nil, nil
	}

	// On engines that don't expose named schemas (MySQL, TiDB, ClickHouse, etc.),
	// drop the schema filter and note the drop. The backend applies `schema == "..."`
	// as an exact match, so passing a non-empty hint like "public" on MySQL would
	// filter out every table. Results are still returned; the note tells the caller
	// why the parameter was ignored.
	var warnings []string

View on GitHub (pinned to 1870550677)

Solutions

  1. Pass a concrete database resource name in the `database` field.
  2. Resolve the target database via the discovery tooling before calling getSchema.
  3. Validate the argument non-empty (after trimming) client-side.

Example fix

// before
SchemaInput{Include: "tables"}
// after
SchemaInput{Database: "instances/prod/databases/appdb", Include: "tables"}
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(input.Database) == "" { return errors.New("database is required before calling getSchema") }

Type guard

func hasDatabase(in SchemaInput) bool { return strings.TrimSpace(in.Database) != "" }

Try / catch

result, err := getSchemaTool(ctx, input)
if err != nil && strings.Contains(err.Error(), "database is required") {
    return fmt.Errorf("getSchema needs a database resource name: %w", err)
}

Prevention

When it happens

Trigger: Calling the `getSchema` MCP tool with `input.Database == ""` — omitting the `database` argument or passing an empty string; also whitespace-only values not rejected before this check.

Common situations: An AI agent skips database discovery and guesses the call; a workflow propagates an empty variable after a failed lookup; the caller confuses schema name with database name.

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/31e269cd8d698894. Report an issue: GitHub.