{"record":{"id":"b6d66f78e4cff390","repo":"BloopAI/vibe-kanban","slug":"migration-db-pool-error","errorCode":null,"errorMessage":"Migration DB pool error: {}","messagePattern":"Migration DB pool error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/services/src/services/execution_process.rs","lineNumber":33,"sourceCode":"use futures::{StreamExt, TryStreamExt};\nuse indicatif::{ProgressBar, ProgressStyle};\nuse sqlx::SqlitePool;\nuse tokio::{io::AsyncWriteExt, sync::RwLock, task::JoinHandle};\nuse utils::{\n    assets::prod_asset_dir_path,\n    execution_logs::{\n        ExecutionLogWriter, process_log_file_path, process_log_file_path_in_root,\n        read_execution_log_file,\n    },\n    log_msg::LogMsg,\n    msg_store::MsgStore,\n};\nuse uuid::Uuid;\n\npub async fn migrate_execution_logs_to_files() -> Result<()> {\n    let pool = DBService::new_migration_pool()\n        .await\n        .map_err(|e| anyhow::anyhow!(\"Migration DB pool error: {}\", e))?;\n\n    if !ExecutionProcessLogs::has_any(&pool).await? {\n        return Ok(());\n    }\n\n    let is_tty = std::io::stderr().is_terminal();\n    if is_tty {\n        let _ = writeln!(\n            std::io::stderr(),\n            \"Performing one time database migration to move logs from SQLite to flat file to improve performance, data remains local, may take a few minutes, please don't exit while this process is running...\"\n        );\n    }\n\n    let pb = if is_tty {\n        Some(new_spinner(\"Migrating\"))\n    } else {\n        None\n    };","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/crates/services/src/services/execution_process.rs#L15-L51","documentation":"migrate_execution_logs_to_files opens a dedicated SQLite migration pool before copying execution logs to files. If the pool cannot be created (database file missing, locked, permissions, bad URL), the underlying error is wrapped in this message and the migration aborts.","triggerScenarios":"Running the log-file migration (startup/upgrade path) when DBService::new_migration_pool fails — bad DATABASE_URL, missing/moved SQLite file, another process holding the DB lock, or read-only filesystem.","commonSituations":"Upgrading the app while another instance is still running and locking the DB; moving the data directory without updating the DB path env; permission changes after an OS update; disk full.","solutions":["Check the inner error text (after 'Migration DB pool error:') for the real cause (locked, no such file, permission denied).","Stop other app instances that may hold the SQLite lock, then retry the migration.","Verify the DB path/env var points at the existing database file.","Fix filesystem permissions on the DB file and its directory, and ensure the disk isn't full."],"exampleFix":"// before\nDATABASE_URL=sqlite:///old/path/vibe.db\n// after\nDATABASE_URL=sqlite:///correct/data/dir/vibe.db  # and ensure no other instance is running","handlingStrategy":"try-catch","validationCode":"// before running migration\nlet db_path = std::env::var(\"DATABASE_URL\")?;\nif !Path::new(&db_path.trim_start_matches(\"sqlite://\")).exists() {\n    anyhow::bail!(\"database file missing at {}\", db_path);\n}","typeGuard":null,"tryCatchPattern":"match migrate_execution_logs_to_files().await {\n    Err(e) if e.to_string().starts_with(\"Migration DB pool error\") => {\n        eprintln!(\"fix DB path/lock and retry: {e}\");\n        // e.g. stop other instances, then retry once\n    }\n    other => other,\n}","preventionTips":["Run only one app instance against the SQLite database at a time.","Keep DATABASE_URL stable when moving data directories.","Check DB file permissions and free disk space before upgrades."],"tags":["database","migration","sqlite","startup"],"backgroundTag":"database-connection-pool-failure","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}