gitbutlerapp/gitbutler · error
existing session ' ' is missing updated-at
Error message
existing session '{session_key}' is missing updated-at What it means
session_list_entry reads the `:updated-at` GitMeta key for a session that an index lookup said exists. Because the index claimed the session exists, its updated-at stamp is expected to be present; a missing value means the stored session data is incomplete or was partially written/corrupted, so the function bails instead of silently dropping the session.
Solutions
- Remove the stale index entry and re-record the session so updated-at is written atomically with the index entry
- Inspect the GitMeta keys under the session prefix (e.g. via the tooling/debug output) to confirm which keys are missing
- Upgrade or rerun the writer to completion; check the writer code path that inserts both the index hit and updated-at
- If this recurs, migrate/rebuild the GitMeta store for the repo
Example fix
// before (caller assumed complete data)
let sessions = find_related_sessions_limited(&repo_path, target, Some(10))?;
// after (tolerate partially-written sessions)
let sessions = find_related_sessions_limited(&repo_path, target, Some(10))
.unwrap_or_else(|_| Vec::new()); // or log and skip per-entry failures Defensive patterns
Strategy: validation
Validate before calling
let prefix = format!("{}:{session_key}", status_prefix(status));
let present = gitmeta_key_exists(&repo_path, &format!("{prefix}:updated-at"));
if !present { /* repair or skip this session */ } Try / catch
match session_list_entry(handle, status, key) {
Ok(entry) => Some(entry),
Err(e) if e.to_string().contains("missing updated-at") => {
// prune stale index entry, skip session
None
}
Err(e) => return Err(e),
} Prevention
- Always write the index entry and updated-at key together (or detail first, reference second)
- Never delete updated-at keys without removing the corresponding index entries
- Add a repair pass that removes index hits lacking session payloads
- Check for crashes/interrupts after writes; rebuild GitMeta after abnormal termination
When it happens
Trigger: find_related_sessions_limited_by_statuses -> session_list_entry when the GitMeta set index lists session_key but handle.get_value('<prefix>:updated-at') returns None — i.e. the session record was never fully written or the updated-at key was deleted.
Common situations: A crash mid-write left an index entry without the session payload; manual pruning of GitMeta keys removed updated-at but not the index entry; older versions of the tool wrote different keys (schema/upgrade drift); corrupted GitMeta storage.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- existing GitMeta key
- existing GitMeta key
- existing GitMeta key
- existing GitMeta key
- existing GitMeta key
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/bd4aabf66ee093aa.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-agentlog/src/gitmeta/read.rs:61
RelatedTarget::Branch(key)
| RelatedTarget::Review(key)
| RelatedTarget::Change(key) => key,
}
}
}
fn session_list_entry(
handle: &SessionTargetHandle<'_>,
status: PublicationStatus,
session_key: String,
) -> Result<SessionListEntry> {
let session_prefix = session_storage_prefix(status, &session_key);
let updated_at_key = format!("{session_prefix}:updated-at");
let updated_at = match handle
.get_value(&updated_at_key)
.with_context(|| format!("failed to read GitMeta key '{updated_at_key}'"))?
{
None => bail!("existing session '{session_key}' is missing updated-at"),
Some(MetaValue::String(updated_at)) => updated_at,
Some(_) => bail!("existing GitMeta key '{updated_at_key}' is not a string"),
};
let sort_updated_at = DateTime::parse_from_rfc3339(&updated_at)
.with_context(|| format!("existing GitMeta key '{updated_at_key}' has invalid timestamp"))?
.with_timezone(&Utc);
Ok(SessionListEntry {
session_key,
status,
updated_at,
sort_updated_at,
})
}
pub(crate) fn find_related_sessions_limited(
repo_path: &Path,
target: RelatedTarget<'_>,
max_sessions: Option<usize>,View on GitHub (pinned to 58e5313667)