Skip to content

fix: use open_in_memory() for DB init fallback to avoid PermissionDenied panic#646

Open
txf0096 wants to merge 1 commit intogit-ai-project:mainfrom
txf0096:fix/sqlite-fallback-open-in-memory
Open

fix: use open_in_memory() for DB init fallback to avoid PermissionDenied panic#646
txf0096 wants to merge 1 commit intogit-ai-project:mainfrom
txf0096:fix/sqlite-fallback-open-in-memory

Conversation

@txf0096
Copy link
Contributor

@txf0096 txf0096 commented Mar 6, 2026

Problem

On systems where /tmp is permission-restricted, git-ai checkpoint panics:

called `Result::unwrap()` on an `Err` value: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }

Backtrace:

 8: core::result::unwrap_failed
 9: git_ai::commands::git_ai_handlers::handle_checkpoint
10: git_ai::main

Root Cause

When InternalDatabase::new() fails (e.g. due to SQLITE_BUSY from concurrent processes), both global() functions fall back to a dummy connection via std::env::temp_dir(). On systems where /tmp is noexec or permission-restricted, Connection::open(&temp_path).expect(...) panics — turning a graceful degradation into a crash.

// src/authorship/internal_db.rs and src/metrics/db.rs
let temp_path = std::env::temp_dir().join("git-ai-db-failed");
let conn = Connection::open(&temp_path).expect("Failed to create temp DB"); // panics on PermissionDenied

Additionally, the fixed path git-ai-db-failed is shared across all processes — if multiple processes hit the fallback simultaneously, they contend on the same file, potentially causing the same lock error again.

The comment already describes the intent:

// Create a dummy connection that will fail on any operation
// This allows the program to continue even if DB init fails

Fix

Replace the fallback with an in-memory connection in both src/authorship/internal_db.rs and src/metrics/db.rs:

let conn = Connection::open_in_memory()
    .expect("Failed to create in-memory fallback DB");
Mutex::new(InternalDatabase {
    conn,
    _db_path: PathBuf::new(),
})

open_in_memory() matches the original intent exactly — all SQL operations still fail (no schema initialized), the program continues without panic, no filesystem dependency, and each process gets its own independent connection.

Impact

  • git-ai stats is not affected (reads from git notes, not internal_db)
  • Core AI attribution tracking is not affected (DB writes are non-fatal)
  • Affected when fallback triggers: git-ai search, git-ai prompts, git-ai show-prompt, git-ai share — return errors or empty results (same as before, just without the panic)

Fixes #645

…ied panic

When DB initialization fails, the fallback path used std::env::temp_dir()
to create a dummy SQLite connection. On systems where /tmp is noexec or
permission-restricted, Connection::open(&temp_path).expect(...) panics.

Replace with Connection::open_in_memory() which:
- Never touches the filesystem, so no permission issues
- Produces the same behavior (all SQL fails, no schema initialized)
- Gives each process its own independent connection instead of
  contending on a shared fixed-path file

Fixes git-ai-project#645
@git-ai-cloud-dev
Copy link

No AI authorship found for these commits. Please install git-ai to start tracking AI generated code in your commits.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQLite "database is locked" causes panic when /tmp is permission-restricted

1 participant