sipeed/picoclaw · critical

must be in range 1-65535

Error message

must be in range 1-65535

What it means

Startup-time port validation in web/backend/main.go. effectivePort (from flag, env, or config resolution) is parsed with strconv.Atoi and range-checked; an out-of-range integer produces this error, a non-integer surfaces the Atoi error, and either way logger.Fatalf terminates the process before listeners open. This is deliberate fail-fast: the launcher refuses to run on an unusable port.

Source

Thrown at web/backend/main.go:564

	}

	if hostOverrideActive && explicitPublic {
		logger.InfoC("web", "Ignoring -public because launcher host was explicitly set")
	}

	if decision := launcherAllowlistBypassLogPolicy(hostInput, effectivePublic, launcherCfg); decision.emit {
		switch decision.level {
		case logger.WARN:
			logger.WarnC("web", decision.message)
		default:
			logger.InfoC("web", decision.message)
		}
	}

	portNum, err := strconv.Atoi(effectivePort)
	if err != nil || portNum < 1 || portNum > 65535 {
		if err == nil {
			err = errors.New("must be in range 1-65535")
		}
		logger.Fatalf("Invalid port %q: %v", effectivePort, err)
	}

	openResult, err := openLauncherListeners(hostInput, effectivePublic, effectivePort)
	if err != nil {
		logger.Fatalf("Failed to open launcher listener(s): %v", err)
	}
	listeners := openResult.Listeners

	dashboardSessionCookie, dashErr := middleware.NewLauncherDashboardSessionCookie()
	if dashErr != nil {
		logger.Fatalf("Dashboard auth setup failed: %v", dashErr)
	}

	// Open the bcrypt password store (creates the DB file on first run).
	authStore, authStoreErr := dashboardauth.New(picoHome)
	var passwordStore api.PasswordStore

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Set a valid port: an integer between 1 and 65535 (unprivileged users need >1024)
  2. Print the effective value before launching to catch env/flag precedence surprises
  3. In wrapper scripts, validate with a one-liner before exec: case "$PORT" in ''|*[!0-9]*|0|655[3-6][5-9]*) echo bad port; exit;; esac
  4. If you meant 'any free port', pick one yourself (net.Listen :0 then close) because this launcher does not accept 0

Example fix

// before
logger.Fatalf("Invalid port %q: %v", effectivePort, err)

// after (validate before startup, in the caller)
portNum, err := strconv.Atoi(portStr)
if err != nil || portNum < 1 || portNum > 65535 {
    return fmt.Errorf("port %q must be in range 1-65535", portStr)
}
Defensive patterns

Strategy: validation

Validate before calling

func validPort(s string) bool {
    n, err := strconv.Atoi(strings.TrimSpace(s))
    return err == nil && n >= 1 && n <= 65535
}

if !validPort(os.Getenv("PORT")) {
    return fmt.Errorf("PORT must be 1-65535, got %q", os.Getenv("PORT"))
}

Prevention

When it happens

Trigger: Launching with -port 0, -port 65536, -port 8080t, or an env/config value that resolves to those; whitespace or a trailing newline in a port env var making Atoi fail.

Common situations: Typo'd flag in a systemd unit or Dockerfile; CI overriding PORT with an empty or invalid value; scripts passing a computed port that can exceed 65535 after adding an offset.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/c8d184ff2937291d. Report an issue: GitHub.