gitbutlerapp/gitbutler · error
existing GitMeta key '{sources_key}' is not a set
Error message
existing GitMeta key '{sources_key}' is not a set What it means
The PR projection reads each session's `:sources` key (e.g. `gitbutler:agent-session:<key>:sources`) as a `MetaValue::Set` of source identifiers, then reads per-source label keys. A missing key means no sources; an existing key that is not a Set bails, aborting the whole projection for the requested sessions.
Source
Thrown at crates/but-agentlog/src/projection.rs:714
fn session_source_metadata<'a>(
repo_path: &Path,
session_keys: impl IntoIterator<Item = &'a String>,
) -> Result<BTreeMap<String, Vec<ProjectionAgentLabel>>> {
let gitmeta = Session::open(repo_path).context("failed to open GitMeta session")?;
let target = Target::project();
let handle = gitmeta.target(&target);
let mut output = BTreeMap::new();
for session_key in session_keys {
let session_prefix = format!("gitbutler:agent-session:{session_key}");
let sources_key = format!("{session_prefix}:sources");
let sources = match handle
.get_value(&sources_key)
.with_context(|| format!("failed to read GitMeta key '{sources_key}'"))?
{
None => BTreeSet::new(),
Some(MetaValue::Set(values)) => values.into_iter().collect(),
Some(_) => bail!("existing GitMeta key '{sources_key}' is not a set"),
};
let mut labels = Vec::new();
for source_key in sources {
let source_prefix = format!("{session_prefix}:source:{source_key}");
let label = ProjectionAgentLabel {
agent: optional_string_value(&handle, &format!("{source_prefix}:agent"))?,
provider: optional_string_value(&handle, &format!("{source_prefix}:provider"))?,
model: optional_string_value(&handle, &format!("{source_prefix}:model"))?,
tool_version: optional_string_value(
&handle,
&format!("{source_prefix}:tool-version"),
)?,
};
if label.agent.is_some() || label.provider.is_some() || label.model.is_some() {
labels.push(label);
}
}
labels.sort_by(|lhs, rhs| {View on GitHub (pinned to caf1f223d3)
Solutions
- Run `but agentlog sync` and retry the projection
- Re-capture the affected sessions under the current `but` build so `:sources` is rewritten as a Set
- Align `but` versions across all machines contributing agentlog data
- Restore the last Set-valued key from GitMeta history or delete it (absence reads as 'no sources')
Example fix
// before
Some(_) => bail!("existing GitMeta key '{sources_key}' is not a set"),
// after: treat a malformed sources key as no sources
let sources = match handle.get_value(&sources_key)? {
Some(MetaValue::Set(values)) => values.into_iter().collect(),
_ => BTreeSet::new(),
}; Defensive patterns
Strategy: type-guard
Validate before calling
// Before projecting, verify each session's sources key variant
if let Some(value) = handle.get_value(&sources_key)? {
if !matches!(value, MetaValue::Set(_)) { /* skip session in this projection */ }
} Type guard
fn sources_is_set(v: Option<&MetaValue>) -> bool {
matches!(v, Some(MetaValue::Set(_)))
} Try / catch
let sources = match handle.get_value(&sources_key)? {
Some(MetaValue::Set(values)) => values.into_iter().collect(),
_ => BTreeSet::new(),
}; Prevention
- Project only over sessions captured by the current but generation
- Sync before running projections on shared repos
- Keep source keys but-agentlog-owned; no external writers
When it happens
Trigger: Building a projection over sessions where one session's `:sources` key holds a String or List — e.g. state written by an incompatible but-agentlog version or mangled via a metadata merge.
Common situations: Mixed `but` versions across contributor machines pushing to the same GitMeta remote; projections run over sessions captured by pre-release builds; manual key edits.
Related errors
- existing GitMeta key '{key}' is not a string
- existing GitMeta key '{updated_at_key}' is not a string
- existing GitMeta key '{index_key}' is not a set
- existing GitMeta key '{associated_targets_key}' is not a str
- existing GitMeta key '{turns_key}' is not a list
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/2f6e1e0f71163d3e.
Report an issue: GitHub.