{"record":{"id":"e498deac6e6839c6","repo":"sinelaw/fresh","slug":"failed-to-read","errorCode":null,"errorMessage":"Failed to read {}: {}","messagePattern":"Failed to read (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-parser-js/src/lib.rs","lineNumber":366,"sourceCode":"\n    Ok(output)\n}\n\n/// Collect all modules in dependency order (dependencies first)\nfn collect_modules(\n    path: &Path,\n    visited: &mut HashSet<PathBuf>,\n    modules: &mut Vec<ModuleMetadata>,\n    path_to_var: &mut std::collections::HashMap<PathBuf, String>,\n) -> Result<()> {\n    let canonical = path.canonicalize().unwrap_or_else(|_| path.to_path_buf());\n    if visited.contains(&canonical) {\n        return Ok(()); // Already processed (circular import protection)\n    }\n    visited.insert(canonical.clone());\n\n    let source = std::fs::read_to_string(path)\n        .map_err(|e| anyhow!(\"Failed to read {}: {}\", path.display(), e))?;\n\n    // Extract module metadata using AST\n    let (imports, exports, reexports) = extract_module_bindings(&source);\n\n    let parent_dir = path.parent().unwrap_or(Path::new(\".\"));\n\n    // Collect dependencies first (topological order)\n    for import in &imports {\n        if import.source_path.starts_with(\"./\") || import.source_path.starts_with(\"../\") {\n            let resolved = resolve_import(&import.source_path, parent_dir)?;\n            collect_modules(&resolved, visited, modules, path_to_var)?;\n        }\n    }\n    for reexport in &reexports {\n        if reexport.source_path.starts_with(\"./\") || reexport.source_path.starts_with(\"../\") {\n            let resolved = resolve_import(&reexport.source_path, parent_dir)?;\n            collect_modules(&resolved, visited, modules, path_to_var)?;\n        }","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-parser-js/src/lib.rs#L348-L384","documentation":"While recursively walking a plugin bundle's import graph, `collect_modules` tries to read each imported file from disk; any I/O failure (missing file, permission, invalid UTF-8 via read_to_string) is wrapped with the path and the underlying io::Error. Bundling cannot proceed without the module's contents.","triggerScenarios":"Calling `collect_modules` (directly or via bundle_module) on an entry file whose imports point to a path that doesn't exist, is a directory, lacks read permission, or contains non-UTF-8 bytes.","commonSituations":"Plugin imports a typo'd relative path; module file deleted or moved after the import was written; importing a node_modules package that isn't vendored on disk; file saved with a non-UTF-8 encoding.","solutions":["Fix or create the file at the path shown in the message.","Correct the import specifier in the importing module to match the actual file name/case.","Vendor or remove imports of external packages (e.g. node_modules-only deps) not present in the bundle root.","Re-save the file as UTF-8 if it contains invalid bytes."],"exampleFix":"// before\nimport { helper } from \"./heplper.ts\"; // typo\n// after\nimport { helper } from \"./helper.ts\";","handlingStrategy":"try-catch","validationCode":"// Check entry and its import targets exist before bundling\nlet p = std::path::Path::new(entry);\nif !p.is_file() { bail!(\"entry file missing: {}\", entry); }","typeGuard":null,"tryCatchPattern":"match bundle_module(entry) {\n    Err(e) if e.to_string().starts_with(\"Failed to read \") => {\n        log::error!(\"bundle aborted, missing module: {e}\");\n        disable_plugin(entry);\n    }\n    other => other?,\n}","preventionTips":["Use relative, case-correct import paths and verify files exist after moves/renames.","Vendor all third-party imports into the plugin directory.","Save sources as UTF-8 and add a pre-bundle existence check for each import."],"tags":["filesystem","module-resolution","plugins","io"],"backgroundTag":"file-read-failed","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}