sipeed/picoclaw · error

failed to create log directory: %w

Error message

failed to create log directory: %w

What it means

InitPanic(filePath) — which installs the deferred panic-capture writer — starts with os.MkdirAll(filepath.Dir(filePath), 0o755). If the panic-log directory cannot be created, the wrapped OS error is returned and panic capture is not installed, so later panics would only reach the regular logger.

Source

Thrown at pkg/logger/panic.go:16

package logger

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime/debug"
	"time"
)

var panicWriter io.WriteCloser

func InitPanic(filePath string) (func(), error) {
	if err := os.MkdirAll(filepath.Dir(filePath), 0o755); err != nil {
		return nil, fmt.Errorf("failed to create log directory: %w", err)
	}
	writer := initPanicFile(filePath)
	if writer == nil {
		return nil, fmt.Errorf("failed to create log file: %s", filePath)
	}
	if panicWriter != nil {
		_ = panicWriter.Close()
	}
	panicWriter = writer
	return func() {
		defer func() {
			writer.Close()
			panicWriter = nil
		}()
		if err := recover(); err != nil {
			RecoverPanicNoExit(err)

			os.Exit(1)

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Point the panic log at a writable directory the process owns
  2. Pre-create the directory with the right ownership before start
  3. Clear any file occupying a directory component of the panic path

Example fix

# before: unprivileged process
InitPanic("/var/log/picoclaw/panic.log")

# after: writable location, dir pre-created
// install -d -o appuser /home/app/.picoclaw/logs
InitPanic("/home/app/.picoclaw/logs/panic.log")
Defensive patterns

Strategy: validation

Validate before calling

if err := os.MkdirAll(filepath.Dir(panicPath), 0o755); err != nil {
    return fmt.Errorf("panic log dir uncreateable — choose a writable location: %w", err)
}

Try / catch

if _, err := logger.InitPanic(panicPath); err != nil {
    fmt.Fprintf(os.Stderr, "panic capture disabled (%v); panics will log to stderr only\n", err)
}

Prevention

When it happens

Trigger: Same failure family as EnableFileLogging's mkdir: EACCES on a protected parent (unprivileged process writing under /var/log), ENOTDIR when a path component is a file, EROFS on read-only mounts, path-length limits — triggered at startup when the panic log path is configured.

Common situations: Hardened deployments where the panic log points into /var/log without permissions; the panic path inherited from a config written for a different user; containers with read-only mounts.

Related errors


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