multica-ai/multica · error
create temp file: %w
Error message
create temp file: %w
What it means
The atomic-replace strategy writes the new binary to os.CreateTemp(dir, "multica-update-*") in the same directory as the running executable; failure is wrapped as 'create temp file: %w'. Same-directory is required because the final rename(2) must not cross filesystems. Typical wrapped errors are fs.PathError with EACCES/EROFS/ENOSPC.
Source
Thrown at server/internal/cli/update.go:449
binaryName := "multica"
if runtime.GOOS == "windows" {
binaryName = "multica.exe"
}
var binaryData []byte
if runtime.GOOS == "windows" {
binaryData, err = extractBinaryFromZip(bytes.NewReader(archiveData), binaryName)
} else {
binaryData, err = extractBinaryFromTarGz(bytes.NewReader(archiveData), binaryName)
}
if err != nil {
return "", fmt.Errorf("extract binary: %w", err)
}
// Atomic replace: write to temp file, then rename over the original.
dir := filepath.Dir(exePath)
tmpFile, err := os.CreateTemp(dir, "multica-update-*")
if err != nil {
return "", fmt.Errorf("create temp file: %w", err)
}
tmpPath := tmpFile.Name()
if _, err := tmpFile.Write(binaryData); err != nil {
tmpFile.Close()
os.Remove(tmpPath)
return "", fmt.Errorf("write temp file: %w", err)
}
tmpFile.Close()
// Preserve original file permissions.
info, err := os.Stat(exePath)
if err != nil {
os.Remove(tmpPath)
return "", fmt.Errorf("stat original binary: %w", err)
}
if err := os.Chmod(tmpPath, info.Mode()); err != nil {
os.Remove(tmpPath)View on GitHub (pinned to 2c0912b6ec)
Solutions
- Move the binary to a user-writable location (e.g. ~/.local/bin) or run the update with sufficient privileges for that directory.
- Free disk space if ENOSPC.
- In immutable/container environments, deploy updates externally rather than in-place self-update.
- Check the wrapped fs.PathError for the exact directory and errno.
Example fix
# before: binary in root-owned dir, self-update fails sudo mv multica /usr/local/bin/ # later update hits EACCES # after: keep the binary user-writable mkdir -p ~/.local/bin && mv multica ~/.local/bin/
Defensive patterns
Strategy: validation
Validate before calling
exe, _ := selfexec.Resolve()
exe, _ = filepath.EvalSymlinks(exe)
if info, err := os.Stat(filepath.Dir(exe)); err != nil || !info.IsDir() {
// install dir unusable for self-update
}
// crude writability probe:
probe, err := os.CreateTemp(filepath.Dir(exe), "probe-*")
if err != nil {
// directory not writable: do not attempt in-place update
}
probe.Close()
os.Remove(probe.Name()) Try / catch
out, err := cli.UpdateViaDownload(ver)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && strings.HasPrefix(err.Error(), "create temp file") {
// EACCES/EROFS/ENOSPC on the install dir: relocate binary or free space
}
} Prevention
- Install the binary in a user-writable directory
- Check free disk space before large downloads
- Do not rely on self-update on read-only rootfs containers
When it happens
Trigger: The binary lives in a root-owned directory (/usr/local/bin) and the update runs as a non-root user; a read-only filesystem (immutable OS, squashfs container); the install directory is full (ENOSPC); macOS SIP protecting the path.
Common situations: Installing via a system package manager location and then expecting self-update to work unprivileged; running the daemon in a container with a read-only rootfs; disks at 100% capacity.
Related errors
- mint PAT: response missing token
- daemon profile is not resolved yet; token sync skipped
- runtime local skill discovery timed out
- runtime local skill import failed
- read file: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/50f10b61d028257c.
Report an issue: GitHub.