larksuite/cli · error · skillref.ErrInvalidRemap

%w: target %q: %w

Error message

%w: target %q: %w

What it means

resolveReferences could not parse the remap's target ('To') string into a skill reference; it wraps skillref.ErrInvalidRemap with the offending target and the parse error. Both endpoints of a remap must be canonical skill references.

Source

Thrown at internal/skillpolicy/resolver.go:137

		content = composed
	}
	refs, err := resolveReferences(content, spec.ReferenceRemaps)
	if err != nil {
		return Resolution{}, fmt.Errorf("plugin %q skill spec: %w", owner, err)
	}
	return Resolution{Content: content, References: refs}, nil
}

func resolveReferences(content fs.FS, remaps []platform.SkillRefRemap) (*skillref.Resolver, error) {
	mappings := make([]skillref.Mapping, 0, len(remaps))
	for _, remap := range remaps {
		from, err := skillref.Parse(remap.From())
		if err != nil {
			return nil, fmt.Errorf("%w: source %q: %w", skillref.ErrInvalidRemap, remap.From(), err)
		}
		to, err := skillref.Parse(remap.To())
		if err != nil {
			return nil, fmt.Errorf("%w: target %q: %w", skillref.ErrInvalidRemap, remap.To(), err)
		}
		mappings = append(mappings, skillref.Mapping{From: from, To: to})
	}
	return skillref.New(content, mappings)
}

// distinctOwners returns the unique contributing plugin names in
// first-seen order. Mirrors cmdpolicy.distinctOwners.
func distinctOwners(specs []PluginSkill) []string {
	seen := map[string]bool{}
	owners := make([]string, 0, len(specs))
	for _, s := range specs {
		if !seen[s.PluginName] {
			seen[s.PluginName] = true
			owners = append(owners, s.PluginName)
		}
	}
	return owners

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Read the quoted target value and underlying parse error
  2. Correct To() to a valid canonical skill reference
  3. Add a unit test asserting skillref.Parse succeeds for every remap endpoint
  4. Ensure the target references a skill retained in the composed tree

Example fix

// before
platform.NewSkillRefRemap("deploy", "Release Guide")
// after
platform.NewSkillRefRemap("deploy", "release")
Defensive patterns

Strategy: validation

Validate before calling

if _, err := skillref.Parse(remap.To()); err != nil {
	return fmt.Errorf("invalid remap target %q: %w", remap.To(), err)
}

Try / catch

_, err := skillpolicy.ResolveWithReferences(base, specs)
if errors.Is(err, skillref.ErrInvalidRemap) { /* fix To value */ }

Prevention

When it happens

Trigger: A ReferenceRemaps entry whose From() parses but whose To() fails skillref.Parse: empty target, invalid characters, or malformed path shape. Reached via ResolveWithReferences when remaps are configured.

Common situations: A remap destination typed as a filesystem path ('./guide.md') or containing typos/case errors, often after copying a From line and editing only partially.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/f3c8fa624484859f. Report an issue: GitHub.