{"record":{"id":"8f9497f351371342","repo":"Hmbown/CodeWhale","slug":"workspace-too-large-for-snapshots-over-gb-of-n","errorCode":null,"errorMessage":"workspace too large for snapshots (over {} GB of non-excluded content or > {} entries): {}\n  raise `[snapshots] max_workspace_gb` in config.toml (or set it to 0 to disable the cap) if you want snapshots on this workspace.","messagePattern":"workspace too large for snapshots \\(over (.+?) GB of non-excluded content or > (.+?) entries\\): (.+?)\n  raise `\\[snapshots\\] max_workspace_gb` in config\\.toml \\(or set it to 0 to disable the cap\\) if you want snapshots on this workspace\\.","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"warning","filePath":"crates/tui/src/snapshot/repo.rs","lineNumber":260,"sourceCode":"                    work_tree.display()\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\n            // workspaces that grew past the cap mid-session get the\n            // existing aggressive-pruning path in `snapshot()`.\n            if estimate_workspace_size_bounded(&work_tree, cap_bytes).is_none() {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidInput,\n                    format!(\n                        \"workspace too large for snapshots (over {} GB of non-excluded content or > {} entries): {}\\n  raise `[snapshots] max_workspace_gb` in config.toml (or set it to 0 to disable the cap) if you want snapshots on this workspace.\",\n                        cap_bytes / (1024 * 1024 * 1024),\n                        SIZE_WALK_MAX_ENTRIES,\n                        work_tree.display()\n                    ),\n                ));\n            }\n            let parent = git_dir.parent().ok_or_else(|| {\n                io::Error::new(io::ErrorKind::InvalidInput, \"snapshot dir has no parent\")\n            })?;\n            std::fs::create_dir_all(parent)?;\n            // `git init` here uses the parent directory as the work tree\n            // and stores metadata in `.git`. We then continue to use\n            // explicit `--git-dir` / `--work-tree` flags for every other\n            // command so behaviour is invariant of cwd.\n            let init = crate::dependencies::Git::command()","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/snapshot/repo.rs#L242-L278","documentation":"A first-init size guard in open_or_init_with_cap: before creating a fresh snapshot repo, estimate_workspace_size_bounded walks the workspace and returns None if non-excluded content exceeds cap_bytes (from [snapshots] max_workspace_gb) or the entry count exceeds SIZE_WALK_MAX_ENTRIES. The error is InvalidInput and its message already names the two remedies. The walk only runs on first init — a workspace that fit initially may grow and is instead handled by aggressive pruning in snapshot().","triggerScenarios":"Opening snapshots on a workspace whose non-excluded content is larger than the configured GB cap or has more entries than the walk limit, at the moment the side .git snapshot repo does not yet exist (first snapshot enable on this workspace).","commonSituations":"Pointing Codewhale at a monorepo or a directory containing large vendored artifacts, node_modules-heavy trees without excludes, datasets, or VM images; lowering max_workspace_gb and wiping the snapshot repo; upgrading with a larger default entry limit changed.","solutions":["Raise [snapshots] max_workspace_gb in config.toml to cover the real workspace size","Set [snapshots] max_workspace_gb = 0 in config.toml to disable the cap entirely if you accept the cost","Shrink non-excluded content: add snapshot excludes for vendor/build/data directories or move bulk data out of the workspace","Re-run after shrinking — the guard only fires when the snapshot repo needs first initialization"],"exampleFix":"# before\n# config.toml\n[snapshots]\nmax_workspace_gb = 1   # Err: workspace too large for snapshots ...\n\n# after\n[snapshots]\nmax_workspace_gb = 8   # or 0 to disable the cap","handlingStrategy":"validation","validationCode":"// Before first-time snapshot enable, size-check the workspace the same way the guard does.\nuse walkdir::WalkDir;\nlet entries = WalkDir::new(&ws).into_iter().filter_map(Result::ok).count();\nlet total: u64 = WalkDir::new(&ws).into_iter().filter_map(Result::ok)\n    .filter_map(|e| e.metadata().ok().map(|m| m.len())).sum();\nif total > cap_bytes || entries > entry_limit {\n    // raise [snapshots] max_workspace_gb or shrink/exclude content first\n}","typeGuard":"fn is_workspace_too_large(e: &std::io::Error) -> bool {\n    e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains(\"workspace too large for snapshots\")\n}","tryCatchPattern":null,"preventionTips":["Size-check large workspaces before first snapshot init, not after","Add snapshot excludes for vendor/, target/, node_modules/, datasets up front","Document the chosen max_workspace_gb alongside the repo so teammates inherit it"],"tags":["snapshots","workspace-size","config","first-init","rust"],"backgroundTag":"workspace-size-limit","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}