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 []stringView on GitHub (pinned to 1870550677)
Solutions
- Pass a concrete database resource name in the `database` field.
- Resolve the target database via the discovery tooling before calling getSchema.
- 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
- Resolve the database via discovery tooling before schema lookup
- Distinguish database name from schema name in client configs
- Validate required arguments before tool invocation
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.