{"record":{"id":"db7135046affde95","repo":"Hmbown/CodeWhale","slug":"workspace-snapshots-are-disabled-for-reason-workspace","errorCode":null,"errorMessage":"workspace snapshots are disabled for {reason}: {workspace}","messagePattern":"workspace snapshots are disabled for (.+?): (.+?)","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/snapshot/repo.rs","lineNumber":324,"sourceCode":"    }\n\n    /// Variant of [`Self::open_or_init`] that accepts an explicit\n    /// workspace-size cap. `cap_bytes = 0` disables the cap entirely\n    /// (always snapshot, regardless of size).\n    ///\n    /// When the workspace exceeds the cap and the side repo hasn't\n    /// been initialized yet, returns `Err(InvalidInput)` with a\n    /// \"workspace too large\" reason. Subsequent calls (after the user\n    /// shrinks the workspace or raises the cap via config) succeed.\n    pub fn open_or_init_with_cap(workspace: &Path, cap_bytes: u64) -> io::Result<Self> {\n        let work_tree = workspace\n            .canonicalize()\n            .unwrap_or_else(|_| workspace.to_path_buf());\n        if let Some(reason) = unsafe_workspace_snapshot_reason(\n            &work_tree,\n            crate::config::effective_home_dir().as_deref(),\n        ) {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                format!(\n                    \"{GATE_UNSAFE_LOCATION_MARKER} for {reason}: {}\",\n                    display_workspace_for_gate(workspace)\n                ),\n            ));\n        }\n\n        let _ = ensure_snapshot_dir(&work_tree)?;\n        let git_dir = snapshot_git_dir(&work_tree);\n\n        let needs_init = !git_dir.exists();\n        if needs_init {\n            // First-init size guard. Skipping this on subsequent opens\n            // is intentional: paying a workspace walk on every snapshot\n            // would defeat the purpose of the cap, and a workspace\n            // that fit on first init is allowed to grow within the\n            // existing repo's `MAX_SNAPSHOT_SIZE_MB` budget. Users on","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/snapshot/repo.rs#L306-L342","documentation":"open_or_init_with_cap checks the workspace via unsafe_workspace_snapshot_reason before opening/initializing the snapshot repo. If the work tree is in an unsafe location (e.g. inside the user's effective home directory), it refuses with ErrorKind::InvalidInput, prefixing GATE_UNSAFE_LOCATION_MARKER so callers can detect the gate.","triggerScenarios":"Calling open_or_init_with_cap with a workspace that canonicalizes to a dangerous location such as the home directory itself or a path containing the home dir, per unsafe_workspace_snapshot_reason.","commonSituations":"Launching codewhale with the working directory set to ~ or a mount that canonicalizes into ~; symlinked project paths resolving into the home directory.","solutions":["Run from a dedicated project directory instead of the home directory.","Inspect the reason in the message ('for {reason}: {workspace}') and move the offending path out of the gated location.","If symlinks cause it, resolve/adjust the symlink so the canonical path is a normal project directory."],"exampleFix":"// before\ncd ~ && codewhale            // gated: workspace == home\n// after\ncd ~/projects/myapp && codewhale","handlingStrategy":"validation","validationCode":"let canon = std::fs::canonicalize(workspace).unwrap_or_else(|_| workspace.into());\nlet home = dirs::home_dir().unwrap();\nif canon.starts_with(&home) && canon != home.join(\"projects\") { eprintln!(\"workspace inside home is gated for snapshots\"); }","typeGuard":null,"tryCatchPattern":"match open_or_init_with_cap(ws, cap) {\n    Err(e) if e.to_string().contains(GATE_UNSAFE_LOCATION_MARKER) => eprintln!(\"run from a project directory outside ~\"),\n    r => r?,\n}","preventionTips":["Launch codewhale from a dedicated project directory, never ~","Watch for symlinks that canonicalize into the home directory","Read the reason embedded in the gate message to identify the offending path"],"tags":["snapshot","safety-gate","workspace"],"backgroundTag":"unsafe-snapshot-location","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}