wavetermdev/waveterm · error

timeout waiting for port

Error message

timeout waiting for port

What it means

runBuilderApp enforces a hard 5-second timeout waiting for the builder subprocess to emit its listening port. If no port line appears in time, the process is killed and this error returned. It indicates the app started but never announced a port within the deadline.

Source

Thrown at pkg/buildercontroller/buildercontroller.go:408

		case <-portChan:
		default:
			errChan <- fmt.Errorf("process died before emitting port")
		}
	}()

	timeout := time.NewTimer(5 * time.Second)
	defer timeout.Stop()

	select {
	case port := <-portChan:
		process.Port = port
		return process, nil
	case err := <-errChan:
		cmd.Process.Kill()
		return nil, err
	case <-timeout.C:
		cmd.Process.Kill()
		return nil, fmt.Errorf("timeout waiting for port")
	case <-ctx.Done():
		cmd.Process.Kill()
		return nil, fmt.Errorf("cancelled while waiting for app port: %w", ctx.Err())
	}
}

func (bc *BuilderController) handleBuildError(err error, resultCh chan<- *BuildResult) {
	bc.lock.Lock()
	defer bc.lock.Unlock()
	bc.setStatus_nolock(BuilderStatus_Error, 0, 1, err.Error())

	if resultCh != nil {
		buildOutput := ""
		if bc.outputBuffer != nil {
			lines := bc.outputBuffer.GetLines()
			buildOutput = strings.Join(lines, "\n")
		}
		select {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect captured output lines to see whether a port was printed but not matched, or not printed at all
  2. Retry — transient slowness on first run often clears on subsequent builds
  3. Check the port-detection regex/callback against the app's actual output format
  4. Increase the 5s timeout if the target app legitimately starts slowly

Example fix

// before
timeout := time.NewTimer(5 * time.Second)
// after
timeout := time.NewTimer(15 * time.Second) // allow slow first-run startups
Defensive patterns

Strategy: retry

Try / catch

process, err := bc.runBuilderApp(ctx, ...)
if err != nil && err.Error() == "timeout waiting for port" {
    // retry once; slow first runs often succeed on a warm cache
    process, err = bc.runBuilderApp(ctx, ...)
}

Prevention

When it happens

Trigger: 5s timer expires before the SetLineCallback detects a port line in the app's stdout/stderr output.

Common situations: Slow startup on cold caches or slow machines (first run, large compile); app writes its port in an unexpected format so the callback regex misses it; app blocks before binding (waiting on stdin, network, lock).

Understand the failure class

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/5346e0ea4e65c873. Report an issue: GitHub.