multica-ai/multica · error

refresh skill: %w

Error message

refresh skill: %w

What it means

Returned by the `multica skill refresh` CLI subcommand when POSTing to `/api/skills/{id}/refresh` fails. Refresh makes the server re-fetch the skill bundle from its upstream source before answering, so unlike other skill calls this one can fail because of *upstream* fetch problems (unreachable source URL, changed bundle layout), in addition to the usual transport/auth/404 causes. The CLI deliberately grants a 60s budget (server caps at 45s) to accommodate the upstream round-trip.

Source

Thrown at server/cmd/multica/cmd_skill.go:438

	fmt.Printf("Skill deleted: %s\n", args[0])
	return nil
}

func runSkillRefresh(cmd *cobra.Command, args []string) error {
	client, err := newAPIClient(cmd)
	if err != nil {
		return err
	}

	// The server re-fetches the bundle from the upstream source before
	// answering; give it the same budget as an import (server-side cap: 45s).
	ctx, cancel := context.WithTimeout(context.Background(), cli.AtLeastAPITimeout(60*time.Second))
	defer cancel()

	var result map[string]any
	if err := client.PostJSON(ctx, "/api/skills/"+args[0]+"/refresh", map[string]any{}, &result); err != nil {
		return fmt.Errorf("refresh skill: %w", err)
	}

	output, _ := cmd.Flags().GetString("output")
	if output == "json" {
		return cli.PrintJSON(os.Stdout, result)
	}

	fmt.Printf("Skill updated from source: %s (%s)\n", strVal(result, "name"), strVal(result, "id"))
	return nil
}

func runSkillImport(cmd *cobra.Command, _ []string) error {
	client, err := newAPIClient(cmd)
	if err != nil {
		return err
	}

	importURL, _ := cmd.Flags().GetString("url")

View on GitHub (pinned to 2c0912b6ec)

Solutions

  1. Check the skill's source URL is still valid: `multica skill get <id> --output json` and open the recorded source URL yourself.
  2. If the upstream moved, re-import the skill from the new URL with `multica skill import --url ... --on-conflict overwrite` instead of refreshing.
  3. If the failure is a timeout, retry once — upstream latency is often transient.
  4. Confirm the skill ID exists and the server is reachable (`multica skill get <id>`).

Example fix

// before
multica skill refresh my-skill   # upstream repo moved

// after
multica skill get my-skill --output json | jq .source_url  # verify source
multica skill import --url https://new-host/skill.zip --on-conflict overwrite  # re-point
Defensive patterns

Strategy: retry

Validate before calling

# verify the skill and its upstream source before refreshing
multica skill get "$SKILL_ID" --output json | jq -e '.source_url' > /dev/null || exit 1
curl -fsSI "$(multica skill get "$SKILL_ID" --output json | jq -r .source_url)" > /dev/null || { echo 'upstream unreachable'; exit 1; }

Try / catch

Retry once on timeout-flavored errors (upstream latency is often transient); on persistent failure fall back to re-import with `skill import --url <new-url> --on-conflict overwrite`; distinguish 404 (bad ID — do not retry) from 5xx (upstream problem — re-import instead of retry).

Prevention

When it happens

Trigger: Refreshing a skill whose recorded upstream URL is dead or moved (server-side fetch error → 5xx); refreshing a non-existent skill ID (404); slow upstream exceeding even the 60s client budget (context deadline exceeded); server or network down.

Common situations: A skill imported from a GitHub repo whose archive URL changed or repo went private; upstream host rate-limiting the server; refreshing skills imported from --file (no upstream source) rather than --url; stale ID after database reset.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/ff40d7613432f0c2. Report an issue: GitHub.