{"record":{"id":"b3cdb209c4d94df9","repo":"Hmbown/CodeWhale","slug":"registry-entry-for-name-must-not-point-to-anot","errorCode":null,"errorMessage":"registry entry for '{name}' must not point to another registry","messagePattern":"registry entry for '(.+?)' must not point to another registry","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/skills/install.rs","lineNumber":1070,"sourceCode":"        InstallSource::DirectUrl(url) => Ok(UrlResolution::Resolved(vec![url.clone()])),\n        InstallSource::Registry(name) => {\n            match fetch_registry(network, registry_url).await? {\n                RegistryFetchResult::Loaded(doc) => {\n                    let entry = doc\n                        .skills\n                        .get(name)\n                        .with_context(|| format!(\"skill '{name}' not found in registry\"))?\n                        .clone();\n                    let inner = InstallSource::parse(&entry.source).with_context(|| {\n                        format!(\n                            \"registry entry for '{name}' has invalid source: {}\",\n                            entry.source\n                        )\n                    })?;\n                    // Recurse only one level — registry pointing at registry is\n                    // disallowed to avoid cycles.\n                    if matches!(inner, InstallSource::Registry(_)) {\n                        bail!(\"registry entry for '{name}' must not point to another registry\");\n                    }\n                    // Reuse this function for the inner source so GitHub fallback\n                    // still applies.\n                    Box::pin(candidate_urls(&inner, network, registry_url)).await\n                }\n                RegistryFetchResult::NeedsApproval(host) => Ok(UrlResolution::NeedsApproval(host)),\n                RegistryFetchResult::Denied(host) => Ok(UrlResolution::Denied(host)),\n            }\n        }\n    }\n}\n\n/// Download the first URL whose host the policy allows and which returns 2xx.\n/// Returns `NeedsApproval` if every candidate hit `Prompt`, or `Denied` if every\n/// candidate was denied.\nasync fn download_first_success(\n    urls: &[String],\n    network: &NetworkPolicy,","sourceCodeStart":1052,"sourceCodeEnd":1088,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/skills/install.rs#L1052-L1088","documentation":"When a registry entry's own source string parses back into another Registry source, candidate_urls bails to prevent install/update cycles. Registry indirection is capped at one level by design: an entry must resolve to a GitHub repo or a direct URL. This is a registry data error, not client configuration.","triggerScenarios":"The registry index contains an entry whose source field is a bare name (parsed as Registry) or another registry-style spec instead of 'github:...' or 'https://...'. Installing that entry fails right after the index is fetched.","commonSituations":"Registry authors nesting references expecting recursive resolution, URLs that lost their scheme and fell back to Registry classification in InstallSource::parse, and third-party registry forks with experimental entries.","solutions":["Fix the registry entry's source to a concrete 'github:owner/repo' or https URL; the fix belongs in the registry data.","If you operate the registry, lint entries by parsing each source and rejecting Registry-typed results.","As an end user, install the underlying GitHub repo directly and skip the broken entry."],"exampleFix":"# registry entry (before)\n{\"name\": \"pack\", \"source\": \"other-registry-name\"}\n\n# after\n{\"name\": \"pack\", \"source\": \"github:owner/pack\"}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn registry_entry_is_concrete(entry: &RegistryEntry) -> bool {\n    !matches!(\n        InstallSource::parse(&entry.source),\n        Ok(InstallSource::Registry(_))\n    )\n}","tryCatchPattern":"match skills::install::install(&spec, &skills_dir, &network).await {\n    Err(err) if err.to_string().contains(\"must not point to another registry\") => {\n        // registry data bug: install the underlying repo directly instead\n    }\n    other => other?,\n}","preventionTips":["If you publish a registry, lint every entry's source field with InstallSource::parse.","Registry entries must carry 'github:owner/repo' or full https URLs, never bare names.","Report nested-registry entries to the registry maintainer instead of working around them client-side."],"tags":["skills","registry","cycle-prevention","data-error","rust"],"backgroundTag":"registry-entry-invalid-source","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}