atuinsh/atuin · error
empty config key
Error message
empty config key
What it means
In set_deep_key, the dotted key is split on '.' and the result is checked; a split of an empty/non-whitespace-validated string can still produce a single empty part. This specific bail is effectively unreachable because split() always yields at least one element (the callers validate non-empty keys first), but it documents the invariant that a key must yield real path segments.
Source
Thrown at crates/atuin/src/command/client/config.rs:323
if v.is_str() {
Some(ValueType::String)
} else if v.is_bool() {
Some(ValueType::Boolean)
} else if v.is_integer() {
Some(ValueType::Integer)
} else if v.is_float() {
Some(ValueType::Float)
} else {
None
}
}
fn set_deep_key(doc: &mut DocumentMut, key: &str, value: Value) -> Result<()> {
let parts: Vec<&str> = key.split('.').collect();
if parts.is_empty() {
eyre::bail!("empty config key");
}
let mut current: &mut dyn TableLike = doc.as_table_mut();
// Navigate/create intermediate tables
for &part in &parts[..parts.len() - 1] {
if !current.contains_key(part) {
current.insert(part, Item::Table(Table::new()));
}
current = current
.get_mut(part)
.expect("just inserted or already exists")
.as_table_like_mut()
.ok_or_else(|| eyre::eyre!("'{}' exists but is not a table", part))?;
}
let last = *parts.last().unwrap();
View on GitHub (pinned to c0c717ab04)
Solutions
- Ensure callers validate the key (non-empty, no whitespace) before calling set_deep_key, as config.rs run/get_updated_config already do.
- If extending the code, reuse the same trim/is_empty/whitespace check upstream of set_deep_key.
- Handle a key consisting only of dots (e.g. ".") which yields empty parts — add a per-part emptiness check if needed.
Example fix
// before
let parts: Vec<&str> = key.split('.').collect();
if parts.is_empty() { bail!("empty config key"); }
// after
let parts: Vec<&str> = key.split('.').collect();
if parts.iter().any(|p| p.is_empty()) { eyre::bail!("invalid dotted key: {key}"); } Defensive patterns
Strategy: validation
Validate before calling
// caller-side guard before building dotted keys
fn ensure_dotted_key(key: &str) -> Result<(), String> {
if key.split('.').any(|p| p.is_empty()) { return Err(format!("bad dotted key: {key}")); }
Ok(())
} Prevention
- Never construct dotted keys by naive concatenation that can yield empty segments.
- Validate keys at CLI entry, as config.rs does.
- Add tests covering keys like "." and "a..b" if extending config internals.
When it happens
Trigger: Directly reachable only if set_deep_key is called with a key that splits into zero parts — practically impossible via the CLI since `run`/`get_updated_config` trim and reject empty keys beforehand. Triggerable in principle by calling the internal function with an empty key.
Common situations: Not encountered by normal users; relevant only to contributors hacking on the config command internals or calling set_deep_key from new code paths without the upstream validation.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- '{}' is a table; use a dotted key like '{}.key' to set a val
- Failed to deserialize theme: {}
- failed to set absolute path override for {key}
- Config key must be non-empty and must not contain whitespace
- Empty theme directory override and could not find theme else
AI-assisted analysis of atuinsh/atuin@c0c717ab04 (2026-09-12).
Data as JSON: /api/errors/2093b598c05661ce.
Report an issue: GitHub.