larksuite/cli · error

invalid plugin name %q: must match ^[a-z0-9][a-z0-9-]*$

Error message

invalid plugin name %q: must match ^[a-z0-9][a-z0-9-]*$

What it means

NewPlugin in extension/platform validates the plugin name against ^[a-z0-9][a-z0-9-]*$ and records this error on the Builder. The name must start with a lowercase letter or digit and contain only lowercase alphanumerics and hyphens.

Source

Thrown at extension/platform/builder.go:62

	skillsOverlay *SkillsOverlay

	hookNames map[string]bool
	errs      []error
}

var pluginNamePattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)

// NewPlugin starts a Builder. Name format is validated lazily — errors
// surface at Build()/MustBuild() time, allowing chained calls without
// intermediate error handling.
func NewPlugin(name, version string) *Builder {
	b := &Builder{
		name:      name,
		version:   version,
		hookNames: map[string]bool{},
	}
	if !pluginNamePattern.MatchString(name) {
		b.errs = append(b.errs, fmt.Errorf("invalid plugin name %q: must match ^[a-z0-9][a-z0-9-]*$", name))
	}
	return b
}

// RequireCLI sets Capabilities.RequiredCLIVersion (semver constraint,
// e.g. ">=1.1.0"). Empty string means no requirement.
func (b *Builder) RequireCLI(constraint string) *Builder {
	b.caps.RequiredCLIVersion = constraint
	return b
}

// FailOpen sets Capabilities.FailurePolicy = FailOpen. Default when
// neither FailOpen nor FailClosed is called and neither Restrict nor
// EmbeddedSkills is used. Build rejects a final FailOpen state after either
// safety-sensitive contribution.
func (b *Builder) FailOpen() *Builder {
	b.caps.FailurePolicy = FailOpen
	return b

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Rename the plugin to lowercase kebab-case, e.g. "my-plugin"
  2. Normalize the name before calling NewPlugin: lowercase and replace '_'/' ' with '-'
  3. Check that the name does not start with '-' or contain consecutive invalid characters
  4. Read the error's %q value to see the exact offending string

Example fix

// before
b := platform.NewPlugin("My_Plugin", "1.0.0")
// after
b := platform.NewPlugin("my-plugin", "1.0.0")
Defensive patterns

Strategy: validation

Validate before calling

var pluginNameRe = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`)
if !pluginNameRe.MatchString(name) { return fmt.Errorf("bad plugin name %q", name) }

Try / catch

b := platform.NewPlugin(name, ver)
if len(b.Errs()) > 0 { /* inspect b.Errs() for the name error before building */ }

Prevention

When it happens

Trigger: Calling NewPlugin with a name containing uppercase letters, underscores, spaces, or starting with a hyphen, e.g. NewPlugin("My_Plugin", "1.0.0").

Common situations: Porting plugin names from camelCase or snake_case conventions; names derived from directory or Go package names; typos or copied product names with spaces.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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