{"record":{"id":"e2a8948e3344fbfc","repo":"zeroclaw-labs/zeroclaw","slug":"skills-extra-registries-url-is-not-a-valid-url","errorCode":null,"errorMessage":"skills.extra_registries[{}].url is not a valid URL: {e}","messagePattern":"skills\\.extra_registries\\[(.+?)\\]\\.url is not a valid URL: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/schema.rs","lineNumber":22000,"sourceCode":"                        \"skills.extra_registries[{}].url must not be empty\",\n                        reg.name\n                    );\n                }\n                if reg.kind != ExternalRegistryKind::Git {\n                    anyhow::bail!(\n                        \"skills.extra_registries[{}].kind must be 'git' (got '{}'); other protocols are not yet supported\",\n                        reg.name,\n                        reg.kind\n                    );\n                }\n                match reqwest::Url::parse(&reg.url) {\n                    Ok(u) if matches!(u.scheme(), \"http\" | \"https\" | \"file\") => {}\n                    Ok(u) => anyhow::bail!(\n                        \"skills.extra_registries[{}].url scheme '{}' is unsupported (use http, https, or file)\",\n                        reg.name,\n                        u.scheme()\n                    ),\n                    Err(e) => anyhow::bail!(\n                        \"skills.extra_registries[{}].url is not a valid URL: {e}\",\n                        reg.name\n                    ),\n                }\n            }\n        }\n\n        // Notion\n        if self.notion.enabled {\n            if self.notion.database_id.trim().is_empty() {\n                anyhow::bail!(\"notion.database_id must not be empty when notion.enabled = true\");\n            }\n            if self.notion.poll_interval_secs == 0 {\n                validation_bail!(\n                    InvalidNumericRange,\n                    \"notion.poll_interval_secs\",\n                    \"notion.poll_interval_secs must be greater than 0\"\n                );","sourceCodeStart":21982,"sourceCodeEnd":22018,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/schema.rs#L21982-L22018","documentation":"Config::validate() reports this when reqwest::Url::parse itself fails on a skills.extra_registries[].url value, with the underlying parse error ({e}) included. Unlike the scheme check, this means the string is not a parseable absolute URL at all: missing scheme, spaces, control characters, or scp-style \"git@host:path\" syntax that is not a real URL.","triggerScenarios":"url = \"git@git.example.com:team/skills.git\" (scp syntax, no scheme), url = \"not a url\", or url with unencoded spaces/quotes in a registry block failing parse during Config::validate().","commonSituations":"Pasting the GitHub/GitLab SSH clone string (git@github.com:org/repo.git) which is scp syntax, not a URL; forgetting the scheme; values corrupted by quotes/smart quotes from documentation copy-paste.","solutions":["Convert scp syntax to https: git@github.com:org/repo.git -> https://github.com/org/repo.git","Ensure the URL has an explicit scheme (https:// or file://) and no raw spaces","Run the value through a URL parse (e.g. `python -c 'from urllib.parse import urlparse...'` or reqwest in a scratch test) before shipping the config"],"exampleFix":"# before\n[[skills.extra_registries]]\nname = \"team\"\nurl = \"git@github.com:acme/skills.git\"\n\n# after\n[[skills.extra_registries]]\nname = \"team\"\nurl = \"https://github.com/acme/skills.git\"","handlingStrategy":"validation","validationCode":"// Pre-flight: the string must be a parseable absolute URL\nfn registry_url_parses(url: &str) -> bool {\n    reqwest::Url::parse(url).is_ok()\n}","typeGuard":"fn registry_url_parses(url: &str) -> bool {\n    reqwest::Url::parse(url.trim()).is_ok()\n}","tryCatchPattern":"match config.validate() {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"is not a valid URL\") => {\n        // e echoes the parse error; most often scp syntax 'git@host:path' -> use https://host/...\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Never paste `git@host:path` clone strings; translate them to https:// first","Always include the scheme; quote URLs in TOML to avoid whitespace artifacts","Test candidate URLs with Url::parse in a scratch test before committing config"],"tags":["config","skills","registry","url","parsing"],"backgroundTag":"invalid-url-format","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}