{"record":{"id":"deee73ada13e9495","repo":"Hmbown/CodeWhale","slug":"plugin-agent-component-is-unavailable","errorCode":null,"errorMessage":"plugin Agent component is unavailable: {}","messagePattern":"plugin Agent component is unavailable: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/profile.rs","lineNumber":249,"sourceCode":"    Ok((profiles, issues))\n}\n\npub(crate) fn load_plugin_agent_profiles_from_component(\n    component: &Path,\n    authority: &crate::plugins::types::PluginAuthority,\n) -> Result<(Vec<AgentProfile>, Vec<String>)> {\n    let (mut profiles, issues) = if component.is_dir() {\n        load_agent_profiles_from_dir_tolerant(component, ProfileOrigin::Plugin)?\n    } else if component.is_file() {\n        match load_agent_profile_file(component) {\n            Ok(mut profile) => {\n                profile.origin = ProfileOrigin::Plugin;\n                (vec![profile], Vec::new())\n            }\n            Err(error) => (Vec::new(), vec![format!(\"{error:#}\")]),\n        }\n    } else {\n        return Err(anyhow!(\n            \"plugin Agent component is unavailable: {}\",\n            component.display()\n        ));\n    };\n    for profile in &mut profiles {\n        profile.plugin_authority = Some(authority.clone());\n    }\n    Ok((profiles, issues))\n}\n\n/// Read only the identity-bearing fields from workspace profiles for the\n/// authoring collision gate.  Unknown legacy fields are harmless here because\n/// no profile behavior is loaded or executed from this representation.\npub fn load_workspace_agent_profile_identities(\n    workspace: impl AsRef<Path>,\n) -> Result<Vec<AgentProfileIdentity>> {\n    let dir = workspace.as_ref().join(WORKSPACE_AGENT_PROFILE_DIR);\n    load_agent_profile_identities_from_dir(dir)","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/profile.rs#L231-L267","documentation":"Fleet agent-profile loading accepts a plugin's Agent component as either a directory of TOML profiles or a single profile file. This error fires when the component path is neither — it does not exist, is a broken symlink, or is something else (fifo/socket). Unlike a malformed profile (which degrades to a warning issue list), a missing component is a hard error because the plugin declared an Agent capability that cannot be loaded at all.","triggerScenarios":"A plugin manifest declaring an agents component path that does not exist in the installed plugin (bad relative path, files not shipped, broken symlink), or a plugin directory partially copied/extracted.","commonSituations":"Plugin packaging bugs omitting the agents folder; plugins installed by git clone with a submodule left uninitialized; manifest paths written for a different plugin layout version; moving/renaming the plugin directory after registration.","solutions":["Check the printed path: does it exist relative to the plugin root? Create it, fix the manifest's component path, or ship the missing files.","Reinstall or fully extract the plugin; for git-based installs run submodule update / restore missing files.","If the plugin should have no agents, remove the Agent component entry from its manifest rather than pointing at nothing.","For broken symlinks, restore the link target or replace it with real files."],"exampleFix":"# before: plugin.toml declares a component that is absent\n[components]\nagents = \"agents/\"        # plugins/foo/agents/ does not exist\n\n# after: ship the directory or point at the real file\n[components]\nagents = \"agents/\"        # plugins/foo/agents/*.toml present","handlingStrategy":"validation","validationCode":"fn plugin_agent_component_usable(path: &Path) -> bool {\n    path.is_dir() || path.is_file() // false for missing paths, broken symlinks, specials\n}\n\nif !plugin_agent_component_usable(&component) {\n    // fail plugin load with a clear message before profile collection\n}\n","typeGuard":"fn existing_file_or_dir(p: &Path) -> Option<&Path> {\n    (p.is_file() || p.is_dir()).then_some(p)\n}\n","tryCatchPattern":"match load_plugin_agent_component(component, authority) {\n    Err(e) if e.to_string().contains(\"plugin Agent component is unavailable\") => {\n        // plugin packaging defect: skip plugin's agents, report to plugin author; do not crash the app\n    }\n    other => other?,\n}","preventionTips":["Validate declared component paths at plugin install time.","Run 'ls -l' on shipped plugin trees in packaging CI to catch missing folders/symlinks.","For git-based plugin installs, initialize submodules during install.","Prefer plugin manifests that omit the agents component when the plugin ships none."],"tags":["fleet","plugin","agent-profiles","filesystem","not-found"],"backgroundTag":"file-not-found","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}