{"record":{"id":"07be51b8512244e1","repo":"gastownhall/beads","slug":"database-name-cannot-be-empty","errorCode":null,"errorMessage":"database name cannot be empty","messagePattern":"database name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/history.go","lineNumber":31,"sourceCode":")\n\n// validTablePattern matches valid table names\nvar validTablePattern = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)\n\n// validDatabasePattern matches valid MySQL database names (alphanumeric, underscore, hyphen)\nvar validDatabasePattern = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_\\-]*$`)\n\n// validateRef checks if a ref is safe to use in queries.\n// Delegates to issueops.ValidateRef.\nfunc validateRef(ref string) error {\n\treturn issueops.ValidateRef(ref)\n}\n\n// ValidateDatabaseName checks if a database name is safe to use in queries.\n// Prevents SQL injection via backtick escaping in CREATE DATABASE statements.\nfunc ValidateDatabaseName(name string) error {\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"database name cannot be empty\")\n\t}\n\tif len(name) > 64 {\n\t\treturn fmt.Errorf(\"database name too long\")\n\t}\n\tif !validDatabasePattern.MatchString(name) {\n\t\treturn fmt.Errorf(\"invalid database name: %s\", name)\n\t}\n\treturn nil\n}\n\n// validateTableName checks if a table name is safe to use in queries\nfunc validateTableName(table string) error {\n\tif table == \"\" {\n\t\treturn fmt.Errorf(\"table name cannot be empty\")\n\t}\n\tif len(table) > 64 {\n\t\treturn fmt.Errorf(\"table name too long\")\n\t}","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/history.go#L13-L49","documentation":"ValidateDatabaseName rejects an empty database name before it can be interpolated into SQL. It is the first of several checks (empty, >64 chars, pattern match) guarding against SQL injection via backtick escaping in CREATE DATABASE / query construction.","triggerScenarios":"BootstrapFromRemoteWithDB, openServerConnection, or other callers pass an empty string as the database name — typically an unset config field or an empty env var (e.g. BEADS_DB unset).","commonSituations":"Config struct field never populated; environment variable empty rather than unset so the default isn't applied; CLI flag provided as empty string; remote URL parsed without a database component.","solutions":["Set the database name in config or via the environment variable before calling the API","Add an early check/flag default so an empty name is replaced with the intended database","If derived from a remote URL, verify the URL includes the database path segment","Run ValidateDatabaseName yourself at config-load time to fail fast with a clear message"],"exampleFix":"// before\nstore, err := BootstrapFromRemoteWithRemote(ctx, remoteURL, \"\") // empty DB\n// after\ndbName := os.Getenv(\"BEADS_DB\")\nif err := dolt.ValidateDatabaseName(dbName); err != nil {\n\treturn fmt.Errorf(\"configure a database name: %w\", err)\n}\nstore, err := BootstrapFromRemoteWithRemote(ctx, remoteURL, dbName)","handlingStrategy":"validation","validationCode":"func requireDBName(name string) error {\n\tif strings.TrimSpace(name) == \"\" {\n\t\treturn errors.New(\"database name must be set (check config / env)\")\n\t}\n\treturn nil\n}\nif err := requireDBName(cfg.Database); err != nil { return err }","typeGuard":"func hasDatabaseName(name string) bool { return strings.TrimSpace(name) != \"\" }","tryCatchPattern":"if err := dolt.ValidateDatabaseName(name); err != nil {\n\tswitch {\n\tcase err.Error() == \"database name cannot be empty\": // fix config\n\tcase strings.Contains(err.Error(), \"too long\"): // truncate/choose shorter name\n\tdefault: // invalid chars, sanitize\n\t}\n}","preventionTips":["Validate DB name at config load with ValidateDatabaseName","Distinguish unset vs empty env vars when defaulting","Derive DB names from URLs only after verifying the path segment exists"],"tags":["dolt","validation","database-name","config"],"backgroundTag":"missing-database-name","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}