larksuite/cli · error

pnpm not found in PATH: %w

Error message

pnpm not found in PATH: %w

What it means

RunPnpmInstall first resolves `pnpm` via exec.LookPath before running `pnpm add -g`. If pnpm is not on PATH, the returned NpmResult.Err wraps the LookPath error with this message, so the pnpm-based update path cannot proceed.

Source

Thrown at internal/selfupdate/updater.go:266

	cmd := exec.CommandContext(ctx, npmPath, "install", "-g", NpmPackage+"@"+version)
	cmd.Stdout = &r.Stdout
	cmd.Stderr = &r.Stderr
	r.Err = cmd.Run()
	if ctx.Err() == context.DeadlineExceeded {
		r.Err = fmt.Errorf("npm install timed out after %s", npmInstallTimeout)
	}
	return r
}

// RunPnpmInstall executes pnpm add -g @larksuite/cli@<version>.
func (u *Updater) RunPnpmInstall(version string) *NpmResult {
	if u.PnpmInstallOverride != nil {
		return u.PnpmInstallOverride(version)
	}
	r := &NpmResult{}
	pnpmPath, err := exec.LookPath("pnpm")
	if err != nil {
		r.Err = fmt.Errorf("pnpm not found in PATH: %w", err)
		return r
	}
	ctx, cancel := context.WithTimeout(context.Background(), npmInstallTimeout)
	defer cancel()
	cmd := exec.CommandContext(ctx, pnpmPath, "add", "-g", NpmPackage+"@"+version)
	cmd.Stdout = &r.Stdout
	cmd.Stderr = &r.Stderr
	r.Err = cmd.Run()
	if ctx.Err() == context.DeadlineExceeded {
		r.Err = fmt.Errorf("pnpm install timed out after %s", npmInstallTimeout)
	}
	return r
}

func (u *Updater) FetchSkillsIndex(source string) *NpmResult {
	if u.SkillsIndexFetchOverride != nil {
		return u.SkillsIndexFetchOverride()
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Install pnpm (`npm install -g pnpm` or `corepack enable pnpm`) and retry the update
  2. Verify with `which pnpm` / `where pnpm` that pnpm resolves in the same shell/environment running the CLI
  3. Add the pnpm install bin directory (e.g. corepack/volta shims) to PATH for the environment invoking lark-cli
  4. Fall back to the npm update path (`npm install -g @larksuite/cli@latest`) or run the CLI's built-in update with npm

Example fix

// before
res := updater.RunPnpmInstall("1.2.3")
if res.Err != nil { log.Fatal(res.Err) }
// after
if _, err := exec.LookPath("pnpm"); err != nil {
	log.Print("pnpm unavailable; falling back to npm")
	res := updater.RunNpmInstall("1.2.3")
	if res.Err != nil { log.Fatal(res.Err) }
} else {
	res := updater.RunPnpmInstall("1.2.3")
	if res.Err != nil { log.Fatal(res.Err) }
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := exec.LookPath("pnpm"); err != nil {
	// pnpm missing: choose npm path or install pnpm before calling RunPnpmInstall
}

Type guard

func pnpmAvailable() bool { _, err := exec.LookPath("pnpm"); return err == nil }

Prevention

When it happens

Trigger: Calling Updater.RunPnpmInstall(version) (directly or via the pnpm install-method detection) when pnpm is not installed or is not in the process's PATH environment variable.

Common situations: pnpm never installed on the machine; pnpm installed via a version manager (corepack, volta, asdf) whose shims are not on the PATH of the process invoking the CLI; PATH differs under cron/CI/systemd; user switched from npm to pnpm or vice versa after install.

Related errors


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