{"record":{"id":"8492f6290b1e2084","repo":"multica-ai/multica","slug":"create-skill-w","errorCode":null,"errorMessage":"create skill: %w","messagePattern":"create skill: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_skill.go","lineNumber":332,"sourceCode":"\t}\n\tif hasContent && content != \"\" {\n\t\tbody[\"content\"] = content\n\t}\n\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\tctx, cancel := cli.APIContext(context.Background())\n\tdefer cancel()\n\n\tvar result map[string]any\n\tif err := client.PostJSON(ctx, \"/api/skills\", body, &result); err != nil {\n\t\treturn fmt.Errorf(\"create 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 created: %s (%s)\\n\", strVal(result, \"name\"), strVal(result, \"id\"))\n\treturn nil\n}\n\nfunc runSkillUpdate(cmd *cobra.Command, args []string) error {\n\tclient, err := newAPIClient(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbody := map[string]any{}","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_skill.go#L314-L350","documentation":"Returned by `multica skill create` when the HTTP POST /api/skills via client.PostJSON fails. All client-side validation (name, content, config JSON) has already passed, so this is a transport or server-side failure: unreachable server, auth error, or the server rejecting the payload (e.g. duplicate name, validation rules) with a non-2xx status.","triggerScenarios":"Creating a skill while the server is down or the token is expired; posting a name that collides with an existing skill; server-side schema constraints (name length, reserved keys in config) rejecting the body.","commonSituations":"Repeated scripted creates without idempotency hitting unique-name rules; self-hosted server behind a proxy with a small body limit; stale auth token after server reinstall.","solutions":["Read the wrapped error for status: 401/403 → `multica login`; 4xx with validation text → fix the payload.","If it's a duplicate, `multica skill list` to find the existing skill and use `multica skill update <id>` instead.","Verify the server is up (`multica daemon status` / health endpoint) for connection failures.","Retry after transient 5xx; check server logs for persistent rejections."],"exampleFix":"# before: blind re-create in a script\nmultica skill create --name lint --content-file ./s.md\n# after: idempotent update-if-exists\nid=$(multica skill list --output json | jq -r '.[] | select(.name==\"lint\") | .id')\n[ -n \"$id\" ] && multica skill update \"$id\" --content-file ./s.md || multica skill create --name lint --content-file ./s.md","handlingStrategy":"try-catch","validationCode":"# Pre-flight auth and connectivity before create\nmultica auth status >/dev/null 2>&1 || { echo \"not authenticated\"; exit 2; }\nmultica skill list >/dev/null 2>&1 || { echo \"API unreachable\"; exit 2; }","typeGuard":null,"tryCatchPattern":"Branch on wrapped cause: 401/403 → re-login; duplicate/validation 4xx → switch to `multica skill update <existing-id>`; connection/5xx → retry with backoff; log the server's message verbatim.","preventionTips":["Make scripted creates idempotent (lookup-by-name, then update-or-create).","Authenticate and check reachability before bulk skill operations.","Keep skill names unique to avoid server-side collisions."],"tags":["go","cli","http","network","skills","validation"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}