Hmbown/CodeWhale · error

memory note is empty

Error message

memory note is empty

What it means

`normalize_note` collapses a note's whitespace into a single line and rejects it if nothing remains. This validation runs before any memory write (remember/revise/retire evidence paths) so empty or whitespace-only notes never enter the store.

Solutions

  1. Check the note content before calling and skip the call if trimmed text is empty.
  2. Fix the upstream producer that yielded blank text (unset variable, failed extraction).
  3. If trimming a prefix like '-' empties the note, supply real content rather than the marker.

Example fix

// before
let note = std::env::var("NOTE").unwrap_or_default();
store.remember(&note).await?;
// after
let note = std::env::var("NOTE")?;
if !note.trim().is_empty() {
    store.remember(&note).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

// Gate the call on non-empty content
if note.trim().trim_start_matches('-').trim().is_empty() {
    return Ok(()); // skip: nothing to store
}

Prevention

When it happens

Trigger: Calling `remember`, `revise`, or `retire` with an empty string, a whitespace-only string, or a string whose only content is stripped during normalization (e.g. just "-").

Common situations: An agent forwards an empty tool argument; upstream code passes an unset variable; a template produced only a bullet marker; a failed extraction yields blank text.

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


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/4a0940a5e2652f45. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/native_memory.rs:888

}

/// Evidence is required on every in-place edit and held to the same bounds
/// as a note. An unexplained rewrite of durable context is the thing the
/// journal exists to prevent.
fn normalize_evidence(evidence: &str) -> Result<String> {
    normalize_note(evidence).map_err(|_| anyhow!("memory edits require non-empty evidence"))
}

fn normalize_note(note: &str) -> Result<String> {
    let note = note.replace("\r\n", "\n").replace('\r', "\n");
    let note = note
        .lines()
        .map(str::trim)
        .filter(|line| !line.is_empty())
        .collect::<Vec<_>>()
        .join(" ");
    if note.is_empty() {
        bail!("memory note is empty");
    }
    if note.len() > MAX_NOTE_BYTES {
        bail!("memory note exceeds {MAX_NOTE_BYTES} bytes");
    }
    Ok(note.trim_start_matches('-').trim().to_string())
}

fn validate_query(query: &str) -> Result<&str> {
    let query = query.trim();
    if query.is_empty() || query.chars().count() > MAX_QUERY_CHARS {
        bail!("memory search query is empty or too long");
    }
    Ok(query)
}

fn safe_component(value: &str) -> Result<String> {
    if value.is_empty()
        || value == "."

View on GitHub (pinned to 433685b202)