{"record":{"id":"f51e8b45b9e3ce09","repo":"multica-ai/multica","slug":"update-skill-w","errorCode":null,"errorMessage":"update skill: %w","messagePattern":"update skill: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_skill.go","lineNumber":384,"sourceCode":"\tif cmd.Flags().Changed(\"config\") {\n\t\tv, _ := cmd.Flags().GetString(\"config\")\n\t\tvar config any\n\t\tif err := json.Unmarshal([]byte(v), &config); err != nil {\n\t\t\treturn fmt.Errorf(\"--config must be valid JSON: %w\", err)\n\t\t}\n\t\tbody[\"config\"] = config\n\t}\n\n\tif len(body) == 0 {\n\t\treturn fmt.Errorf(\"no fields to update; use --name, --description, --content, or --config\")\n\t}\n\n\tctx, cancel := cli.APIContext(context.Background())\n\tdefer cancel()\n\n\tvar result map[string]any\n\tif err := client.PutJSON(ctx, \"/api/skills/\"+args[0], body, &result); err != nil {\n\t\treturn fmt.Errorf(\"update skill: %w\", err)\n\t}\n\n\toutput, _ := cmd.Flags().GetString(\"output\")\n\tif output == \"json\" {\n\t\treturn cli.PrintJSON(os.Stdout, result)\n\t}\n\n\tfmt.Printf(\"Skill updated: %s (%s)\\n\", strVal(result, \"name\"), strVal(result, \"id\"))\n\treturn nil\n}\n\nfunc runSkillDelete(cmd *cobra.Command, args []string) error {\n\tyes, _ := cmd.Flags().GetBool(\"yes\")\n\tif !yes {\n\t\tfmt.Printf(\"Are you sure you want to delete skill %s? This cannot be undone. [y/N] \", args[0])\n\t\treader := bufio.NewReader(os.Stdin)\n\t\tanswer, _ := reader.ReadString('\\n')\n\t\tanswer = strings.TrimSpace(strings.ToLower(answer))","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_skill.go#L366-L402","documentation":"Returned by the `multica skill update` CLI subcommand when the HTTP PUT to `/api/skills/{id}` fails. The underlying error is wrapped with %w, so the cause is one of: transport failure (server unreachable, timeout, TLS), a non-2xx API response (most often 404 unknown skill ID or 400 invalid field), or a JSON decode failure of the response body. The CLI has already validated that at least one of --name/--description/--content/--config was provided, so the failure is on the API side, not local flag validation.","triggerScenarios":"Running `multica skill update <id> --description \"...\"` where <id> does not exist (404); server not running or wrong --api-url; API key lacks permission; sending a --config value the server rejects as invalid JSON/YAML; request exceeded the default API context timeout.","commonSituations":"Typo'd or stale skill ID copied from an earlier `skill list` output; local dev server restarted with a fresh database so previous IDs no longer resolve; CLI pointed at a different environment (prod vs localhost) than the one holding the skill; expired or missing auth token.","solutions":["Verify the skill exists first: `multica skill list --output json` (or `multica skill get <id>`) and confirm the exact ID.","Check server reachability and environment: confirm the CLI's --api-url / auth flags point at the server that actually owns the skill.","If --config was passed, validate it is well-formed before sending (e.g. `cat config.json | jq .`) since malformed config triggers a 400.","Inspect the wrapped error text: a 404 means bad ID, a 400 means invalid payload, a connection refused means wrong host/port."],"exampleFix":"// before\nmultica skill update abc123 --config '{bad json'\n\n// after\nmultica skill get abc123   # confirm the ID resolves\njq . config.json            # confirm the config payload is valid\nmultica skill update abc123 --config \"$$(cat config.json)\"","handlingStrategy":"try-catch","validationCode":"# confirm the target exists and the payload is well-formed before updating\nmultica skill get \"$SKILL_ID\" --output json > /dev/null || exit 1\njq -e . config.json > /dev/null || { echo 'invalid config JSON'; exit 1; }","typeGuard":null,"tryCatchPattern":"In Go or shell wrappers, capture the wrapped error and branch on cause: if strings.Contains(err.Error(), \"404\") treat as bad-ID (re-list skills), if \"connection refused\" fix environment, else surface the message. Since the CLI uses %w wrapping, Go callers can errors.As/errors.Is on the underlying client error type.","preventionTips":["Always resolve IDs fresh via `skill list --output json` in the same session instead of hardcoding them.","Validate JSON/YAML config payloads locally (jq / yq) before passing via --config.","Pin the CLI to the same environment (--api-url, auth) that produced the IDs you are using."],"tags":["cli","http","skill","api-error"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}