Hmbown/CodeWhale · error
cannot contain leading or trailing whitespace
Error message
{label} cannot contain leading or trailing whitespace What it means
After checking emptiness, `validated_record_id` also rejects ids with leading or trailing whitespace. Since ids become file names, whitespace would create paths that differ subtly from the logical id, so the trimmed and original values must match exactly.
Solutions
- Call `.trim()` on the id before passing it to the store API.
- Fix the parsing/splitting code so whitespace is not captured in the id.
- Validate/normalize ids at ingestion time (when records are first created).
Example fix
// before store.list_turns_for_thread(&user_supplied_thread_id)?; // after store.list_turns_for_thread(user_supplied_thread_id.trim())?;
Defensive patterns
Strategy: validation
Validate before calling
fn clean_id(id: &str) -> Result<&str, String> { let t = id.trim(); if t != id { Err("id has surrounding whitespace".into()) } else { Ok(t) } } Type guard
fn is_trimmed(id: &str) -> bool { id.trim() == id } Try / catch
match store.list_turns_for_thread(id) { Err(e) if e.contains("whitespace") => store.list_turns_for_thread(id.trim()), Err(e) => Err(e.into()), Ok(v) => Ok(v) } Prevention
- Trim any id parsed from user input, CLI, or files
- Avoid capturing separators when splitting strings into ids
- Normalize ids once at the ingestion boundary
When it happens
Trigger: Passing a thread/turn/item id with surrounding spaces or newlines to any of `record_path`, `save_turn`, `save_item`, `list_turns_for_thread`, `list_items_for_turn`, `list_items_for_turns_map`.
Common situations: Ids parsed from user input, CLI args, or pasted values that carry a trailing space or newline; splitting a string that left a separator behind.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- must not be empty
- must not be empty
- cannot be empty
- contains unsupported characters
- operation_key cannot contain leading or trailing whitespace
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c4d1aab986e6e784.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:300
if let Some(end) = end {
let tail = base[end..].trim_start();
if !tail.is_empty() {
if !out.is_empty() {
out.push_str("\n\n");
}
out.push_str(tail);
}
}
out
}
fn validated_record_id<'a>(id: &'a str, label: &str) -> Result<&'a str> {
let trimmed = id.trim();
if trimmed.is_empty() {
bail!("{label} cannot be empty");
}
if trimmed != id {
bail!("{label} cannot contain leading or trailing whitespace");
}
if !trimmed
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
{
bail!("{label} contains unsupported characters");
}
Ok(trimmed)
}
fn agent_mail_workspace_id(workspace: &Path) -> Result<String> {
let canonical = workspace
.canonicalize()
.with_context(|| format!("resolve Agent Mail workspace {}", workspace.display()))?;
let digest = Sha256::digest(canonical.to_string_lossy().as_bytes());
let digest = digest
.iter()
.map(|byte| format!("{byte:02x}"))View on GitHub (pinned to 73e0f67d83)