larksuite/cli · error

npm install timed out after %s

Error message

npm install timed out after %s

What it means

RunNpmInstall runs `npm install -g @larksuite/cli@<version>` under a context with a fixed timeout (npmInstallTimeout). If cmd.Run() has not returned before the deadline, the context is canceled and the code replaces the underlying error with this message, reporting that npm install exceeded the allowed time.

Source

Thrown at internal/selfupdate/updater.go:253

// RunNpmInstall executes npm install -g @larksuite/cli@<version>.
func (u *Updater) RunNpmInstall(version string) *NpmResult {
	if u.NpmInstallOverride != nil {
		return u.NpmInstallOverride(version)
	}
	r := &NpmResult{}
	npmPath, err := exec.LookPath("npm")
	if err != nil {
		r.Err = fmt.Errorf("npm not found in PATH: %w", err)
		return r
	}
	ctx, cancel := context.WithTimeout(context.Background(), npmInstallTimeout)
	defer cancel()
	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)

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check network connectivity and npm registry reachability (npm ping), then retry the update
  2. Clear or repair the npm cache (`npm cache verify` or `npm cache clean --force`) and retry
  3. Use a faster registry mirror via `npm config set registry <mirror>` if the default registry is slow
  4. If installs legitimately need longer, update the binary manually with `npm install -g @larksuite/cli@latest` outside the CLI's timeout

Example fix

// before
res := updater.RunNpmInstall("1.2.3")
if res.Err != nil { log.Fatal(res.Err) }
// after
res := updater.RunNpmInstall("1.2.3")
if res.Err != nil {
	if strings.Contains(res.Err.Error(), "timed out") {
		// fall back to manual install or retry with better network
		log.Printf("npm install timed out; retry or install manually: %v", res.Err)
	} else {
		log.Fatal(res.Err)
	}
}
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := exec.LookPath("npm"); err != nil { /* fix PATH first */ }
out, err := exec.Command("npm", "ping").CombinedOutput() // check registry reachability before updating

Try / catch

res := updater.RunNpmInstall(version)
if res.Err != nil {
	if strings.Contains(res.Err.Error(), "timed out after") {
		// timeout path: retry or manual install
	} else {
		return res.Err
	}
}

Prevention

When it happens

Trigger: Calling Updater.RunNpmInstall(version) during a self-update when the spawned `npm install -g @larksuite/cli@<version>` process runs longer than npmInstallTimeout, causing context.DeadlineExceeded on the exec context.

Common situations: Slow or saturated network when downloading the package from the npm registry; large install tree; npm cache corruption forcing re-download; corporate proxy or mirror latency; running on a slow CI runner or constrained machine.

Understand the failure class

Related errors


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