larksuite/cli · error

invalid skill reference remap

Error message

invalid skill reference remap

What it means

ErrInvalidRemap is the sentinel in internal/skillref for explicit skill reference mappings (From -> To) that are malformed, conflicting, or dangling. During composition, internal/skillpolicy/resolver.go wraps it when either endpoint of a remap fails skillref.Parse; the skillref resolver itself returns it via New/resolveReferences for bad sources, duplicate sources, or explicit targets that do not exist. Callers classify it as an invalid SkillsOverlay.

Source

Thrown at internal/skillref/resolver.go:14

// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT

package skillref

import (
	"errors"
	"fmt"
	"io/fs"
)

// ErrInvalidRemap identifies malformed, conflicting, or dangling explicit
// reference mappings. Callers classify it as an invalid SkillsOverlay.
var ErrInvalidRemap = errors.New("invalid skill reference remap")

// Mapping is one parsed remap. A source without Path remaps the whole skill
// name; a source with Path is an exact-reference override.
type Mapping struct {
	From Ref
	To   Ref
}

// Resolver is an immutable, build-local projection from canonical references
// to the composed runtime skill tree. Underlying skill files remain live, in
// line with the skill manifest contract, so Resolve verifies availability at
// read/help-render time as well as validating explicit targets at construction.
type Resolver struct {
	content fs.FS
	skills  map[string]Ref
	exact   map[string]Ref
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check the wrapped message for 'source' or 'target' to see which endpoint failed to parse, and fix its skill reference syntax (skill name, optional Path).
  2. Ensure each remap's source is unique across all mappings.
  3. Verify the target skill actually exists in the composed base/plugin tree before shipping the overlay.

Example fix

// before: dangling explicit target
{From: skillref.Parse("old-skill"), To: skillref.Parse("renamed-skill-v2")} // renamed-skill-v2 not shipped
// after: target exists in the tree
{From: skillref.Parse("old-skill"), To: skillref.Parse("renamed-skill")}
Defensive patterns

Strategy: validation

Validate before calling

func validateRemaps(mappings []skillref.Mapping, existing map[string]bool) error {
    seen := map[string]bool{}
    for _, m := range mappings {
        if seen[m.From.String()] { return fmt.Errorf("duplicate remap source %s", m.From) }
        seen[m.From.String()] = true
        if _, ok := existing[m.To.String()]; !ok { return fmt.Errorf("dangling remap target %s", m.To) }
    }
    return nil
}

Type guard

if errors.Is(err, skillref.ErrInvalidRemap) {
    // a From/To endpoint failed to parse or is dangling/conflicting
}

Try / catch

if err := resolve(); err != nil {
    if errors.Is(err, skillref.ErrInvalidRemap) {
        // fix the remap named in the wrapped 'source'/'target' text
    }
}

Prevention

When it happens

Trigger: A remap entry with an unparseable From or To reference (wrapped at resolver.go:133/137); registering a Resolver with a duplicate source (TestResolverRejectsDuplicateSource); an explicit remap target skill that does not exist (TestResolverExplicitTargetMustExist, TestResolveWithReferences_DanglingExplicitRemapFails).

Common situations: Typoed skill names or paths in a plugin's reference remaps; two remaps sharing the same source after copy-paste; renaming a target skill elsewhere without updating remaps, leaving dangling targets.

Related errors


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