larksuite/cli · error

pnpm install timed out after %s

Error message

pnpm install timed out after %s

What it means

RunPnpmInstall runs `pnpm add -g @larksuite/cli@<version>` under a context bounded by npmInstallTimeout. When the command exceeds the deadline, the context is canceled and this error replaces the underlying exec error to explain the timeout.

Source

Thrown at internal/selfupdate/updater.go:276

// 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()
	}

	r := &NpmResult{}
	ctx, cancel := context.WithTimeout(context.Background(), skillsIndexFetchTimeout)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, skillsIndexURL(source), nil)
	if err != nil {
		r.Err = err
		return r
	}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check connectivity and pnpm registry configuration (`pnpm config get registry`), then retry the update
  2. Warm or clean the pnpm store (`pnpm store prune`) and retry
  3. Use a faster registry mirror via `pnpm config set registry <mirror>`
  4. Install manually outside the timeout: `pnpm add -g @larksuite/cli@latest`

Example fix

// before
res := updater.RunPnpmInstall("1.2.3")
if res.Err != nil { log.Fatal(res.Err) }
// after
res := updater.RunPnpmInstall("1.2.3")
if res.Err != nil {
	if strings.Contains(res.Err.Error(), "timed out") {
		// do the install outside the CLI's bounded timeout
		err := exec.Command("pnpm", "add", "-g", "@larksuite/cli@latest").Run()
		if err != nil { log.Fatal(err) }
	} else {
		log.Fatal(res.Err)
	}
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := exec.LookPath("pnpm"); err != nil { return }
out, err := exec.Command("pnpm", "config", "get", "registry").Output() // confirm a reachable registry

Try / catch

res := updater.RunPnpmInstall(version)
if res.Err != nil {
	if strings.Contains(res.Err.Error(), "timed out after") {
		// handle timeout: manual `pnpm add -g` fallback
	} else {
		return res.Err
	}
}

Prevention

When it happens

Trigger: Calling Updater.RunPnpmInstall(version) during a self-update when the spawned `pnpm add -g` process runs longer than npmInstallTimeout, i.e. ctx.Err() == context.DeadlineExceeded after cmd.Run().

Common situations: Slow network to the npm registry through pnpm's configured store/mirror; cold pnpm store requiring full download; low-resources VM or CI runner; proxy latency; very large install graph triggered by global store misses.

Understand the failure class

Related errors


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