multica-ai/multica · error
import skill: %w
Error message
import skill: %w
What it means
Returned by the `--file` branch of `multica skill import`: the archive was read from disk successfully, but the multipart upload via `client.ImportSkillFile` to `/api/skills/import` failed. Before this generic wrap, `handleSkillImportError` inspects the error for a name-conflict (409) to produce a friendlier message — reaching this line means the failure was NOT a simple conflict: it is a transport error, timeout (60s budget), invalid archive, or a 4xx/5xx from the server.
Source
Thrown at server/cmd/multica/cmd_skill.go:482
onConflict, _ := cmd.Flags().GetString("on-conflict")
if !validSkillImportConflictStrategy(onConflict) {
return fmt.Errorf("--on-conflict must be one of: fail, overwrite, rename, skip")
}
ctx, cancel := context.WithTimeout(context.Background(), cli.AtLeastAPITimeout(60*time.Second))
defer cancel()
var result map[string]any
if importFile != "" {
fileData, readErr := os.ReadFile(importFile)
if readErr != nil {
return fmt.Errorf("read skill archive: %w", readErr)
}
if err := client.ImportSkillFile(ctx, fileData, filepath.Base(importFile), onConflict, &result); err != nil {
if handledErr := handleSkillImportError(cmd, err); handledErr != nil {
return handledErr
}
return fmt.Errorf("import skill: %w", err)
}
return printSkillImportResult(cmd, result)
}
body := map[string]any{
"url": importURL,
"on_conflict": onConflict,
}
if err := client.PostJSON(ctx, "/api/skills/import", body, &result); err != nil {
if handledErr := handleSkillImportError(cmd, err); handledErr != nil {
return handledErr
}
return fmt.Errorf("import skill: %w", err)
}
return printSkillImportResult(cmd, result)
}
View on GitHub (pinned to 2c0912b6ec)
Solutions
- Re-check server reachability/auth with `multica skill list` from the same environment.
- Validate the archive structure: it must contain the expected skill bundle layout (SKILL.md at the expected level) — rebuild it with the same tool that produced working imports.
- If a timeout, retry on a stable connection or import from `--url` instead to let the server fetch directly.
- If the server returned 400/500, check server logs for the concrete validation failure — the CLI message only wraps the status.
Example fix
# before multica skill import --file bundle.zip --on-conflict fail # 400 invalid bundle # after unzip -l bundle.zip # confirm expected skill files at top level multica skill import --file fixed-bundle.zip --on-conflict fail
Defensive patterns
Strategy: try-catch
Validate before calling
# pre-flight: server reachable, archive looks like a zip with expected layout multica skill list > /dev/null || exit 1 command -v unzip >/dev/null && unzip -l "$ARCHIVE" | grep -q SKILL.md || echo 'warning: SKILL.md not visible in archive'
Try / catch
Branch on the wrapped cause: conflict-shaped errors are already handled by handleSkillImportError, so what remains is transport (fix env), 400 invalid-bundle (fix archive layout), or timeout (retry / switch to --url). Log server-side details when the status is 4xx/5xx since the CLI message is generic.
Prevention
- Build archives with the same packaging step that produced known-good imports.
- Keep CLI and server versions in sync — bundle format evolves with the server.
- For large bundles or flaky links, import via --url so the server fetches directly.
When it happens
Trigger: Server unreachable or auth failure; archive is not a valid skill bundle (missing SKILL.md, bad structure) so the server rejects it with 400; upload exceeding the 60s context deadline on slow links or large bundles; server 500 while persisting files.
Common situations: Hand-zipped bundle with wrong top-level layout; local dev server restarted mid-upload; bundle built with a newer format than the running server understands (version skew between CLI and server); network proxy stripping multipart bodies.
Related errors
- upload attachment %s: %w
- update skill: %w
- delete skill: %w
- refresh skill: %w
- either --url or --file is required
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/2166d9ac8998ea96.
Report an issue: GitHub.