{"record":{"id":"eaca556a7603ae42","repo":"Hmbown/CodeWhale","slug":"project-hooks-file-exceeds-the-1-mib-limit","errorCode":null,"errorMessage":"project hooks file exceeds the 1 MiB limit","messagePattern":"project hooks file exceeds the 1 MiB limit","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/hooks/config.rs","lineNumber":16,"sourceCode":"use serde::{Deserialize, Serialize};\nuse std::io::Read as _;\nuse std::path::{Path, PathBuf};\n\n/// Project hook files are executable configuration and must not become an\n/// unbounded startup allocation merely because a trusted repository supplied\n/// a very large file.\nconst PROJECT_HOOKS_FILE_MAX_BYTES: usize = 1024 * 1024;\n\npub(super) fn read_project_hooks_file(path: &Path) -> std::io::Result<String> {\n    let file = std::fs::File::open(path)?;\n    let mut contents = String::new();\n    file.take((PROJECT_HOOKS_FILE_MAX_BYTES + 1) as u64)\n        .read_to_string(&mut contents)?;\n    if contents.len() > PROJECT_HOOKS_FILE_MAX_BYTES {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidData,\n            \"project hooks file exceeds the 1 MiB limit\",\n        ));\n    }\n    Ok(contents)\n}\n\n/// Events that can trigger hook execution\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum HookEvent {\n    /// Triggered when a new session starts\n    SessionStart,\n    /// Triggered when a session ends (quit, Ctrl+C)\n    SessionEnd,\n    /// Triggered before a user message is sent to the LLM\n    MessageSubmit,\n    /// Triggered before a tool is executed","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/hooks/config.rs#L1-L34","documentation":"This error means the project hooks configuration file is larger than the allowed 1 MiB (PROJECT_HOOKS_FILE_MAX_BYTES). The library reads at most limit+1 bytes with a bounded take() and throws InvalidData when the content exceeds the limit, protecting against oversized or pathological hooks files.","triggerScenarios":"Calling load_plugin_hook_component when the project hooks file on disk exceeds PROJECT_HOOKS_FILE_MAX_BYTES (1 MiB) — detected by reading limit+1 bytes and finding contents.len() > limit.","commonSituations":"A generated or vendored hooks file grew unbounded; a script appended repeatedly to hooks config; someone pasted a large blob into the hooks JSON/YAML.","solutions":["Trim the project hooks file below 1 MiB: remove unused hook entries and comments","Move large or generated hook logic into an external script the hooks file invokes, keeping the config small","Split hooks across plugin-level configuration instead of one giant project file"],"exampleFix":"// before\nhooks.json: 1.4 MiB of inline commands\n// after\nhooks.json references scripts: {\"post-edit\": {\"command\": \"./hooks/post-edit.sh\"}}","handlingStrategy":"validation","validationCode":"const LIMIT: u64 = 1024 * 1024;\nlet md = std::fs::metadata(hooks_path)?;\nif md.len() > LIMIT {\n    return Err(\"project hooks file exceeds 1 MiB; trim it before loading\");\n}","typeGuard":null,"tryCatchPattern":"match load_plugin_hook_component(path) {\n    Ok(hooks) => register(hooks),\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        eprintln!(\"hooks file too large (>1 MiB); reduce it\");\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep hooks config declarative and small; move heavy logic into scripts","Monitor generated hooks files for unbounded growth","Split large hook sets across plugin-level configuration"],"tags":["hooks","file-size","config","limit"],"backgroundTag":"file-size-limit-exceeded","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"}