Hmbown/CodeWhale · error
workspace id required
Error message
workspace id required
What it means
`NativeMemory::revise` rewrites an existing memory note, addressed by a scope. When the caller selects `MemoryScope::Workspace`, the workspace identifier is mandatory because the note lives under a per-workspace namespace; the library refuses to guess one and throws this error when `workspace_id` is `None`. This prevents notes from being edited in an ambiguous or wrong workspace scope.
Solutions
- Pass the current workspace id as the second argument when using MemoryScope::Workspace
- Guard the call site: resolve the workspace id first and only call revise once it is Some
- Fall back to MemoryScope::Global if the operation is intended to be global
Example fix
// before
mem.revise(MemoryScope::Workspace, None, from, to, evidence)?
// after
mem.revise(MemoryScope::Workspace, Some("ws-42"), from, to, evidence)? Defensive patterns
Strategy: validation
Validate before calling
fn ensure_workspace_id(scope: MemoryScope, workspace_id: Option<&str>) -> Result<&str> {
match (scope, workspace_id) {
(MemoryScope::Workspace, Some(id)) if !id.is_empty() => Ok(id),
(MemoryScope::Workspace, _) => anyhow::bail!("workspace scope requires an id"),
_ => Ok(""),
}
} Type guard
fn has_workspace_id(scope: &MemoryScope, id: &Option<&str>) -> bool {
!matches!(scope, MemoryScope::Workspace) || id.is_some_and(|s| !s.is_empty())
} Try / catch
match mem.revise(MemoryScope::Workspace, workspace_id, from, to, evidence) {
Ok(hit) => hit,
Err(e) if e.to_string().contains("workspace id required") => resolve_workspace_then_retry(),
Err(e) => return Err(e),
} Prevention
- Thread the active workspace id through all memory API calls, never pass a bare None with Workspace scope
- Centralize memory calls behind a helper that resolves scope+id together
- Default to MemoryScope::Global when no workspace context exists
When it happens
Trigger: Calling `native_memory.revise(MemoryScope::Workspace, None, from, to, evidence)` — i.e. requesting a workspace-scoped correction without supplying the workspace id.
Common situations: A tool or UI handler that receives the scope from config/user input but drops the workspace id; a caller that always passes `None` for the id because it only ever used global scope before switching to workspace memory.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- bad_args
- Checkpoint continuation requires a source agent
- correction must match exactly one active note on the…
- Input exceeds 64 MiB.
- Invalid Engine batch.
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/cf59c160e4828d40.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/native_memory.rs:207
&Snapshot::default(),
)?
} else {
r.memory
};
self.hit(&store, &access, &memory, &Snapshot::default())
}
pub fn revise(
&self,
scope: MemoryScope,
workspace_id: Option<&str>,
from: &str,
to: &str,
evidence: &str,
) -> Result<MemoryHit> {
let selected = match scope {
MemoryScope::Global => Self::owner_scope(),
MemoryScope::Workspace => Self::workspace_scope(
workspace_id.ok_or_else(|| anyhow!("workspace id required"))?,
)?,
};
let access = Access::agent(vec![selected.clone()])?;
let mut store = self.open_structured()?;
let entries = store.list(&access, None, 500)?;
let matches: Vec<_> = entries
.iter()
.filter(|m| m.status == Status::Active && m.draft.body.trim() == from.trim())
.collect();
if matches.len() != 1 {
bail!(
"correction must match exactly one active note on the bounded page; use Context Lens UUIDs"
);
}
let old = matches[0];
let mut draft = Draft::note(
selected,
policy::excerpt(to, 80),View on GitHub (pinned to 73e0f67d83)