larksuite/cli · error

skill reference is empty

Error message

skill reference is empty

What it means

skillref.Parse parses the "name[/relative/path]" reference form used by `skills read`. An empty input string has no skill component, so Parse immediately rejects it. Callers include remap validation in skillref.New and the skills read command path.

Source

Thrown at internal/skillref/ref.go:25

package skillref

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

// Ref is one exact canonical or runtime skill reference. Path is relative to
// the named skill; an empty Path denotes the skill's SKILL.md.
type Ref struct {
	Skill string
	Path  string
}

// Parse parses the "name[/relative/path]" form accepted by `skills read`.
func Parse(raw string) (Ref, error) {
	if raw == "" {
		return Ref{}, fmt.Errorf("skill reference is empty")
	}
	skill, path, _ := strings.Cut(raw, "/")
	if !ValidSkillName(skill) {
		return Ref{}, fmt.Errorf("%q has invalid skill name %q", raw, skill)
	}
	if path != "" && (!fs.ValidPath(path) || path == "." || strings.Contains(path, `\`)) {
		return Ref{}, fmt.Errorf("%q has invalid relative path %q", raw, path)
	}
	if path == "" && strings.HasSuffix(raw, "/") {
		return Ref{}, fmt.Errorf("%q has an empty relative path", raw)
	}
	return Ref{Skill: skill, Path: path}, nil
}

// ValidSkillName reports whether name can identify a top-level skill
// directory. Keep this rule aligned with the skill-tree manifest validator.
func ValidSkillName(name string) bool {
	return name != "" && name != "." && name != ".." && !strings.ContainsAny(name, `/\`)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Provide a non-empty reference like "auth" or "auth/TOKENS.md".
  2. Guard empty input before calling Parse: if raw == "" return early or default to a known skill.
  3. Check why the flag/env is empty (typo in variable name, missing config entry) rather than bypassing validation.
  4. For Mappings, ensure From and To are explicitly constructed, never the zero Ref{}.

Example fix

// before
ref, err := skillref.Parse(os.Getenv("SKILL_REF"))
// after
raw := os.Getenv("SKILL_REF")
if raw == "" {
    return fmt.Errorf("SKILL_REF is not set")
}
ref, err := skillref.Parse(raw)
Defensive patterns

Strategy: validation

Validate before calling

raw := os.Getenv("SKILL_REF")
if strings.TrimSpace(raw) == "" {
    return errors.New("skill reference is required (e.g. auth or auth/TOKENS.md)")
}

Try / catch

ref, err := skillref.Parse(raw)
if err != nil {
    return fmt.Errorf("--skill flag: %w", err)
}

Prevention

When it happens

Trigger: Passing "" to skillref.Parse, or a Mapping whose From.String()/To.String() is empty (zero-value Ref) into skillref.New; an environment/flag variable holding the reference resolves to empty.

Common situations: An unset CLI flag or env var interpolated into a skill reference; constructing Ref{} with both fields empty and calling String(); scripts passing $UNSET_VAR directly to `skills read`.

Related errors


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