wavetermdev/waveterm · critical
filemutex new error: %w
Error message
filemutex new error: %w
What it means
The Windows implementation of AcquireWaveLock creates a filemutex on <WaveDataDir>/<WaveLockFile> to ensure only one Wave instance runs. filemutex.New fails when the lock file path cannot be set up (invalid path, directory missing, or OS-level CreateFile failure), wrapped as 'filemutex new error: %w'.
Source
Thrown at pkg/wavebase/wavebase-win.go:22
//go:build windows
package wavebase
import (
"fmt"
"log"
"path/filepath"
"github.com/alexflint/go-filemutex"
)
func AcquireWaveLock() (FDLock, error) {
dataHomeDir := GetWaveDataDir()
lockFileName := filepath.Join(dataHomeDir, WaveLockFile)
log.Printf("[base] acquiring lock on %s\n", lockFileName)
m, err := filemutex.New(lockFileName)
if err != nil {
return nil, fmt.Errorf("filemutex new error: %w", err)
}
err = m.TryLock()
if err != nil {
return nil, fmt.Errorf("filemutex trylock error: %w", err)
}
return m, nil
}
View on GitHub (pinned to a4447c1563)
Solutions
- Read the wrapped %w error for the exact Windows error code
- Ensure the data directory exists: create GetWaveDataDir()'s path (os.MkdirAll) before acquiring the lock
- Check/fix the WAVE_DATA_DIR override to a valid, writable path
- Run the app as a user with write access to the data directory
Example fix
// before
lock, err := wavebase.AcquireWaveLock() // data dir missing
// after
if err := os.MkdirAll(wavebase.GetWaveDataDir(), 0755); err != nil {
return err
}
lock, err := wavebase.AcquireWaveLock() Defensive patterns
Strategy: try-catch
Validate before calling
dataDir := wavebase.GetWaveDataDir()
if err := os.MkdirAll(dataDir, 0755); err != nil {
return fmt.Errorf("cannot prepare data dir %s: %w", dataDir, err)
}
if err := unix.Access(dataDir, unix.W_OK); err != nil {
return fmt.Errorf("data dir not writable: %w", err)
} Type guard
func dataDirReady() bool {
dir := wavebase.GetWaveDataDir()
info, err := os.Stat(dir)
return err == nil && info.IsDir()
} Try / catch
lock, err := wavebase.AcquireWaveLock()
if err != nil {
if strings.Contains(err.Error(), "filemutex new error") {
// repair path: ensure data dir exists, then retry once
os.MkdirAll(wavebase.GetWaveDataDir(), 0755)
lock, err = wavebase.AcquireWaveLock()
}
if err != nil { return err }
} Prevention
- Do not set WAVE_DATA_DIR to nonexistent or invalid paths
- Ensure the data directory exists at install time and is not removed by cleaners
- Run the app under a user account with write access to the data directory
- On Windows, check antivirus interference with lock-file creation
When it happens
Trigger: Calling AcquireWaveLock at startup when GetWaveDataDir() returns a path that does not exist or is not writable, the path contains illegal characters, or filemutex cannot create/open the lock file on Windows (ERROR_PATH_NOT_FOUND, access denied).
Common situations: WAVE_DATA_DIR env var overridden to a nonexistent or invalid directory; data dir deleted by cleanup tools while the app runs; path with characters Windows rejects; running from a context without permission to the data directory (service account, restricted user).
Related errors
- filemutex trylock error: %w
- setting auth key: %v
- error getting client: %v
- process group id not supported on windows
- sending signals is not supported on Windows
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/000e378c7b61d137.
Report an issue: GitHub.