sipeed/picoclaw · critical

error initializing panic log: %v

Error message

error initializing panic log: %v

What it means

Launcher main() panics when logger.InitPanic(<picoclaw home>/logs/launcher_panic.log) returns an error. InitPanic (pkg/logger/panic.go:14) first MkdirAll's the directory (wrapping failures as 'failed to create log directory') and then creates the file via initPanicFile ('failed to create log file'); any failure propagates here and crashes the launcher at startup before anything else runs.

Source

Thrown at web/backend/main.go:443

			os.Stderr,
			"  %s -public ./config.json\n",
			os.Args[0],
		)
		fmt.Fprintf(os.Stderr, "      Allow access from other devices on the local network\n")
		fmt.Fprintf(os.Stderr, "  %s -host :: ./config.json\n", os.Args[0])
		fmt.Fprintf(os.Stderr, "      Bind launcher host explicitly with exact host semantics\n")
		fmt.Fprintf(os.Stderr, "  %s -console -d ./config.json\n", os.Args[0])
		fmt.Fprintf(os.Stderr, "      Run in the terminal with debug logs enabled\n")
	}
	flag.Parse()

	// Initialize logger
	picoHome := utils.GetPicoclawHome()

	f := filepath.Join(picoHome, logPath, panicFile)
	panicFunc, err := logger.InitPanic(f)
	if err != nil {
		panic(fmt.Sprintf("error initializing panic log: %v", err))
	}
	defer panicFunc()

	enableConsole := *console
	fileLoggingEnabled := shouldEnableLauncherFileLogging(enableConsole, debug)
	if fileLoggingEnabled {
		// GUI mode writes launcher logs to file. Debug mode keeps file logging enabled in console mode too.
		if !debug {
			logger.DisableConsole()
		}

		f := filepath.Join(picoHome, logPath, logFile)
		if err = logger.EnableFileLogging(f); err != nil {
			panic(fmt.Sprintf("error enabling file logging: %v", err))
		}
		defer logger.DisableFileLogging()
	}
	if debug {

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Read the wrapped %v — it distinguishes directory-creation failure from file-creation failure
  2. Make the home's logs directory writable by the runtime user, or point PICO_HOME at a writable location
  3. Clear stale locks (previous instance) and enforce one instance per home
  4. In container specs, add a writable volume for the home/logs path

Example fix

# docker: before (read-only fs, no volume)
# after
VOLUME ["/var/lib/picoclaw"]
ENV PICO_HOME=/var/lib/picoclaw
Defensive patterns

Strategy: validation

Validate before calling

logs := filepath.Join(utils.GetPicoclawHome(), "logs")
if err := os.MkdirAll(logs, 0o755); err != nil {
    return fmt.Errorf("fix writability of %s before launch: %w", logs, err)
}
if probe, err := os.OpenFile(filepath.Join(logs, "launcher_panic.log"), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o600); err != nil {
    return fmt.Errorf("panic log not creatable: %w", err)
} else {
    probe.Close()
}

Try / catch

Process exits at startup: handle at the deploy/supervisor layer — capture stderr, classify the wrapped error (directory vs file creation), and block the rollout until the environment is writable.

Prevention

When it happens

Trigger: Picoclaw home not writable; a logs path component is a regular file; disk full or quota exceeded; PICO_HOME override pointing somewhere invalid; on Windows, the panic log locked by another process.

Common situations: First run in a container without a writable volume; home directory created by root in an earlier run; PICO_HOME set under a read-only mount; two launcher instances sharing one home.

Related errors


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