{"record":{"id":"4bcef4a1159bf665","repo":"sipeed/picoclaw","slug":"invalid-registry-name-w","errorCode":null,"errorMessage":"✗  invalid registry name: %w","messagePattern":"✗  invalid registry name: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/picoclaw/internal/skills/helpers.go","lineNumber":54,"sourceCode":"\t\tfmt.Println(\"No skills installed.\")\n\t\treturn\n\t}\n\n\tfmt.Println(\"\\nInstalled Skills:\")\n\tfmt.Println(\"------------------\")\n\tfor _, skill := range allSkills {\n\t\tfmt.Printf(\"  ✓ %s (%s)\\n\", skill.Name, skill.Source)\n\t\tif skill.Description != \"\" {\n\t\t\tfmt.Printf(\"    %s\\n\", skill.Description)\n\t\t}\n\t}\n}\n\n// skillsInstallFromRegistry installs a skill from a named registry (e.g. clawhub).\nfunc skillsInstallFromRegistry(cfg *config.Config, registryName, target string) error {\n\terr := utils.ValidateSkillIdentifier(registryName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"✗  invalid registry name: %w\", err)\n\t}\n\n\tregistryMgr := skills.NewRegistryManagerFromToolsConfig(cfg.Tools.Skills)\n\n\tregistry := registryMgr.GetRegistry(registryName)\n\tif registry == nil {\n\t\treturn fmt.Errorf(\"✗  registry '%s' not found or not enabled. check your config.json.\", registryName)\n\t}\n\n\tdirName, err := registry.ResolveInstallDirName(target)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"✗  invalid install target %q: %w\", target, err)\n\t}\n\n\tfmt.Printf(\"Installing skill '%s' from %s registry...\\n\", target, registryName)\n\n\tworkspace := cfg.WorkspacePath()\n\ttargetDir := filepath.Join(workspace, \"skills\", dirName)","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/cmd/picoclaw/internal/skills/helpers.go#L36-L72","documentation":"The registry name in `skills install <registry>/<target>` failed utils.ValidateSkillIdentifier before any registry lookup: registry names must satisfy picoclaw's identifier policy (no spaces, slashes, uppercase, or punctuation outside the allowed set). The specific rule broken is in the wrapped error.","triggerScenarios":"skillsInstallFromRegistry receives a registryName with invalid characters — e.g. \"Claw Hub\", \"claw/hub\", or \"clawhub!\" — and ValidateSkillIdentifier rejects it at helpers.go:54.","commonSituations":"Typing the registry's display name instead of its config key, shell quoting mistakes, or a registry key in config.json that itself contains invalid characters.","solutions":["Use the exact registry key from config.json (e.g. clawhub).","Check for typos, stray spaces, and unbalanced shell quotes.","Rename the registry key in config to a valid identifier.","Read the wrapped ValidateSkillIdentifier message for the precise rule violated."],"exampleFix":"# before\npicoclaw skills install \"claw hub/myskill\"\n# after\npicoclaw skills install clawhub/myskill","handlingStrategy":"validation","validationCode":"registryName = strings.TrimSpace(registryName)\nif err := utils.ValidateSkillIdentifier(registryName); err != nil {\n    return fmt.Errorf(\"invalid registry name %q: %w\", registryName, err)\n}","typeGuard":"func validRegistryName(s string) bool {\n    return utils.ValidateSkillIdentifier(s) == nil\n}","tryCatchPattern":null,"preventionTips":["Offer shell completion sourced from the registry keys in config.","Validate registry keys at config-write time so invalid keys can never be referenced.","Normalize input (trim whitespace) before validating."],"tags":["validation","registry","cli","go"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}