{"record":{"id":"cf59c160e4828d40","repo":"Hmbown/CodeWhale","slug":"workspace-id-required","errorCode":null,"errorMessage":"workspace id required","messagePattern":"workspace id required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/native_memory.rs","lineNumber":207,"sourceCode":"                &Snapshot::default(),\n            )?\n        } else {\n            r.memory\n        };\n        self.hit(&store, &access, &memory, &Snapshot::default())\n    }\n    pub fn revise(\n        &self,\n        scope: MemoryScope,\n        workspace_id: Option<&str>,\n        from: &str,\n        to: &str,\n        evidence: &str,\n    ) -> Result<MemoryHit> {\n        let selected = match scope {\n            MemoryScope::Global => Self::owner_scope(),\n            MemoryScope::Workspace => Self::workspace_scope(\n                workspace_id.ok_or_else(|| anyhow!(\"workspace id required\"))?,\n            )?,\n        };\n        let access = Access::agent(vec![selected.clone()])?;\n        let mut store = self.open_structured()?;\n        let entries = store.list(&access, None, 500)?;\n        let matches: Vec<_> = entries\n            .iter()\n            .filter(|m| m.status == Status::Active && m.draft.body.trim() == from.trim())\n            .collect();\n        if matches.len() != 1 {\n            bail!(\n                \"correction must match exactly one active note on the bounded page; use Context Lens UUIDs\"\n            );\n        }\n        let old = matches[0];\n        let mut draft = Draft::note(\n            selected,\n            policy::excerpt(to, 80),","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/native_memory.rs#L189-L225","documentation":"`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.","triggerScenarios":"Calling `native_memory.revise(MemoryScope::Workspace, None, from, to, evidence)` — i.e. requesting a workspace-scoped correction without supplying the workspace id.","commonSituations":"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.","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"],"exampleFix":"// before\nmem.revise(MemoryScope::Workspace, None, from, to, evidence)?\n// after\nmem.revise(MemoryScope::Workspace, Some(\"ws-42\"), from, to, evidence)?","handlingStrategy":"validation","validationCode":"fn ensure_workspace_id(scope: MemoryScope, workspace_id: Option<&str>) -> Result<&str> {\n    match (scope, workspace_id) {\n        (MemoryScope::Workspace, Some(id)) if !id.is_empty() => Ok(id),\n        (MemoryScope::Workspace, _) => anyhow::bail!(\"workspace scope requires an id\"),\n        _ => Ok(\"\"),\n    }\n}","typeGuard":"fn has_workspace_id(scope: &MemoryScope, id: &Option<&str>) -> bool {\n    !matches!(scope, MemoryScope::Workspace) || id.is_some_and(|s| !s.is_empty())\n}","tryCatchPattern":"match mem.revise(MemoryScope::Workspace, workspace_id, from, to, evidence) {\n    Ok(hit) => hit,\n    Err(e) if e.to_string().contains(\"workspace id required\") => resolve_workspace_then_retry(),\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["memory","missing-argument","workspace-scope"],"backgroundTag":"missing-required-argument","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}