JuliusBrussee/caveman · error

native session key create: %w

Error message

native session key create: %w

What it means

OpenFile(O_WRONLY|O_CREAT|O_EXCL) on session.key returned an error other than os.ErrExist. That means the create itself failed for a non-race reason: permission denied on the runtime directory, read-only filesystem, or the path existing as a directory. (The EEXIST case is the normal concurrent-startup path and falls through to reading the existing key.)

Source

Thrown at proxy/internal/nativeruntime/marker.go:54

	file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600)
	if err == nil {
		if _, writeErr := file.Write(key); writeErr != nil {
			_ = file.Close()
			_ = os.Remove(path)
			return nil, fmt.Errorf("native session key write: %w", writeErr)
		}
		if syncErr := file.Sync(); syncErr != nil {
			_ = file.Close()
			_ = os.Remove(path)
			return nil, fmt.Errorf("native session key sync: %w", syncErr)
		}
		if closeErr := file.Close(); closeErr != nil {
			return nil, fmt.Errorf("native session key close: %w", closeErr)
		}
		return key, nil
	}
	if !errors.Is(err, os.ErrExist) {
		return nil, fmt.Errorf("native session key create: %w", err)
	}
	key, err = os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("native session key read: %w", err)
	}
	if len(key) != sessionKeyBytes {
		return nil, fmt.Errorf("native session key length = %d, want %d", len(key), sessionKeyBytes)
	}
	if err := os.Chmod(path, 0o600); err != nil {
		return nil, fmt.Errorf("native session key chmod: %w", err)
	}
	return key, nil
}

// SessionMarker builds model-temporary correlation context. Local proxy removes
// valid markers byte-surgically before provider inspection or forwarding.
func SessionMarker(key []byte, sessionID string) (string, error) {
	if len(key) != sessionKeyBytes || sessionID == "" || len(sessionID) > 256 {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Fix ownership: chown -R runninguser <home>
  2. If the path is a directory, remove it so a regular key file can be created
  3. Remount the volume read-write or point home at writable storage
  4. Check MAC (SELinux/AppArmor) denials in the audit log

Example fix

# before
~/.caveman/runtime owned by root, running as user -> Error[1072]

# after
sudo chown -R $(id -un):$(id -gn) ~/.caveman
Defensive patterns

Strategy: validation

Validate before calling

func canCreateKey(home string) bool {
    dir := filepath.Join(home, "runtime")
    probe, err := os.CreateTemp(dir, ".probe-*")
    if err != nil { return false }
    os.Remove(probe.Name())
    return true
}

Prevention

When it happens

Trigger: runtime dir is 0700 owned by another user; filesystem mounted read-only; <home>/runtime/session.key exists as a directory; SELinux/AppArmor denying writes.

Common situations: Running the binary as a different user than the one who first created ~/.caveman; hardened or read-only root filesystems.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/7bdeb1860dc0a568. Report an issue: GitHub.