sipeed/picoclaw · critical

Failed to redirect stderr to file: %v

Error message

Failed to redirect stderr to file: %v

What it means

Windows-only startup panic: windows.SetStdHandle(STD_ERROR_HANDLE, file) failed after the panic log was created. The code redirects the process's Win32 stderr handle to the file (then reassigns os.Stderr) so Go runtime panics land in launcher_panic.log; when SetStdHandle is denied or the handle arrangement is invalid, crash capture cannot be set up and the process aborts.

Source

Thrown at pkg/logger/panic_win.go:21

package logger

import (
	"fmt"
	"io"
	"os"

	"golang.org/x/sys/windows"
)

func initPanicFile(panicFile string) io.WriteCloser {
	file, err := os.OpenFile(panicFile, os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_APPEND, 0o600)
	if err != nil {
		panic(fmt.Sprintf("error in open panic: %v", err))
	}
	err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(file.Fd()))
	if err != nil {
		panic(fmt.Sprintf("Failed to redirect stderr to file: %v", err))
	}
	os.Stderr = file
	return file
}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Launch with explicit stderr redirection (run from a console or pipe stderr to a file) so STD_ERROR_HANDLE exists
  2. If running as a service, configure the service wrapper to provide std handles
  3. Reproduce from cmd.exe — if the binary starts there, the wrapper configuration is the culprit

Example fix

# before
start /b launcher.exe   # no std handles attached

# after
launcher.exe 2>launch.err.log
Defensive patterns

Strategy: validation

Validate before calling

if os.Stderr == nil || os.Stderr.Fd() == uintptr(windows.InvalidHandle) {
    return errors.New("no valid stderr handle; launch with stderr redirected before logger.InitPanic")
}

Try / catch

Startup abort before app code runs: fix the launch environment (provide std handles) rather than catching anything in-process; verify by running the same binary from a console.

Prevention

When it happens

Trigger: The process has no valid STD_ERROR_HANDLE — GUI-subsystem launch with no console and no redirected stderr, or a service wrapper that started the process with standard handles stripped; sandbox/job-object restrictions on handle replacement; the file handle from OpenFile somehow invalid.

Common situations: Launching the GUI binary through wrappers/tools that strip standard handles; service hosts that provide no std handles; post-injection handle tampering by third-party DLLs.

Related errors


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