{"record":{"id":"55e5ab5b5e418ba2","repo":"semaphoreui/semaphore","slug":"boltdb-not-supported","errorCode":null,"errorMessage":"BoltDB not supported","messagePattern":"BoltDB not supported","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/config.go","lineNumber":2029,"sourceCode":"// GetConnectionString constructs the database connection string based on the current configuration.\n// It supports MySQL, BoltDB, and PostgreSQL dialects.\n// If the dialect is unsupported, it returns an error.\n//\n// Parameters:\n// - includeDbName: a boolean indicating whether to include the database name in the connection string.\n//\n// Returns:\n// - connectionString: the constructed database connection string.\n// - err: an error if the dialect is unsupported.\nfunc (d *DbConfig) GetConnectionString(includeDbName bool) (connectionString string, err error) {\n\tdbName := d.GetDbName()\n\tdbUser := d.GetUsername()\n\tdbPass := d.GetPassword()\n\tdbHost := d.GetHostname()\n\n\tswitch d.Dialect {\n\tcase DbDriverBolt:\n\t\terr = errors.New(\"BoltDB not supported\")\n\t\treturn\n\tcase DbDriverMySQL:\n\t\tif includeDbName {\n\t\t\tconnectionString = fmt.Sprintf(\n\t\t\t\t\"%s:%s@tcp(%s)/%s\",\n\t\t\t\tdbUser,\n\t\t\t\tdbPass,\n\t\t\t\tdbHost,\n\t\t\t\tdbName)\n\t\t} else {\n\t\t\tconnectionString = fmt.Sprintf(\n\t\t\t\t\"%s:%s@tcp(%s)/\",\n\t\t\t\tdbUser,\n\t\t\t\tdbPass,\n\t\t\t\tdbHost)\n\t\t}\n\t\toptions := map[string]string{\n\t\t\t\"parseTime\":         \"true\",","sourceCodeStart":2011,"sourceCodeEnd":2047,"githubUrl":"https://github.com/semaphoreui/semaphore/blob/1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa/util/config.go#L2011-L2047","documentation":"Semaphore no longer supports BoltDB as a database backend. When the resolved database dialect is 'bolt', GetDBConfig (connection string construction) returns the error 'BoltDB not supported' instead of a connection string, and callers abort (e.g. HTTP handlers respond 400).","triggerScenarios":"config has `dialect: bolt` (or only a bolt section), and code that builds a DB connection string (GetDBConfig / buildConnectionString) hits `case DbDriverBolt: err = errors.New(\"BoltDB not supported\")`.","commonSituations":"Upgrading an old Semaphore installation that used BoltDB to a current version; copying legacy config.json with dialect 'bolt' into a new deployment.","solutions":["Migrate data off BoltDB (export via the old version, e.g. `semaphore export` / project JSON export)","Change config to a supported dialect: mysql, postgres (or sqlite), with the corresponding connection section","Remove the `bolt` section / set `dialect` explicitly to the new backend","Restore an exported dataset into MySQL/Postgres before starting the new version"],"exampleFix":"// before (config.json)\n{\"dialect\": \"bolt\", \"bolt\": {\"host\": \"db.bolt\"}}\n// after\n{\"dialect\": \"mysql\", \"mysql\": {\"host\": \"db:3306\", \"user\": \"semaphore\", \"pass\": \"...\", \"name\": \"semaphore\"}}","handlingStrategy":"validation","validationCode":"// reject bolt before calling into semaphore DB config\nif strings.EqualFold(cfg.Dialect, \"bolt\") {\n    return errors.New(\"BoltDB is unsupported; migrate to mysql/postgres/sqlite first\")\n}","typeGuard":null,"tryCatchPattern":"// handlers should translate the returned error instead of crashing\nif err := dbSetup(cfg); err != nil {\n    helpers.WriteErrorStatus(w, err.Error(), http.StatusBadRequest)\n    return\n}","preventionTips":["Migrate off BoltDB before upgrading Semaphore versions","Never carry legacy bolt sections into new deployments","Pin the old Semaphore version if BoltDB data must still be read"],"tags":["go","database","config","boltdb","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"1774ccb71a0a8b82eb74ea24c23ac9ab713de2fa","analyzedAt":"2026-09-07T11:00:33.293Z","contentChangedAt":"2026-09-07T11:00:33.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}