chenhg5/cc-connect · error

resolve home dir: %w

Error message

resolve home dir: %w

What it means

saveAttachment calls os.UserHomeDir() and wraps its failure as "resolve home dir: %w". os.UserHomeDir returns an error when neither $HOME (Unix) nor the Windows user-profile APIs yield a home directory, so the platform cannot compute ~/.cc-connect/attachments and the attachment save aborts.

Source

Thrown at platform/wps-agentspace/wpsagentspace.go:269

		name = "image_" + time.Now().Format("20060102_150405") + ext
	}

	path, err := p.saveAttachment(name, img.Data)
	if err != nil {
		return fmt.Errorf("wps-agentspace: SendImage: %w", err)
	}

	notice := fmt.Sprintf("🖼 图片已保存到本地:\n%s", path)
	return p.sendText(rc.ChatID, notice, rc)
}

// saveAttachment writes data to ~/.cc-connect/attachments/<name> and returns
// the absolute path. The filename is sanitized to a basename to prevent path
// traversal.
func (p *Platform) saveAttachment(name string, data []byte) (string, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return "", fmt.Errorf("resolve home dir: %w", err)
	}
	dir := filepath.Join(home, ".cc-connect", "attachments")
	if err := os.MkdirAll(dir, 0o755); err != nil {
		return "", fmt.Errorf("mkdir: %w", err)
	}

	name = filepath.Base(name)
	if name == "" || name == "." || name == "/" {
		name = fmt.Sprintf("file_%d", time.Now().UnixMilli())
	}
	path := filepath.Join(dir, name)
	if err := os.WriteFile(path, data, 0o644); err != nil {
		return "", fmt.Errorf("write: %w", err)
	}
	return path, nil
}

// Stop gracefully shuts down the platform.

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Set HOME explicitly in the service environment (systemd: Environment=HOME=/home/ccconnect or /var/lib/cc-connect; docker: -e HOME=/home/app).
  2. Run the daemon as a regular user that has a home directory, or create one with useradd -m.
  3. As a caller, pre-check home resolution and fail fast with a clear config error before starting the platform.

Example fix

// before: launching daemon with scrubbed env
cmd := exec.Command("cc-connect")
cmd.Env = []string{"PATH=/usr/bin"}
// after
cmd := exec.Command("cc-connect")
cmd.Env = append(os.Environ(), "HOME=/var/lib/cc-connect")
Defensive patterns

Strategy: validation

Validate before calling

home, err := os.UserHomeDir()
if err != nil || home == "" {
    return errors.New("HOME is not set; configure HOME for the cc-connect process")
}
if fi, err := os.Stat(home); err != nil || !fi.IsDir() {
    return fmt.Errorf("HOME %s is not an existing directory", home)
}

Try / catch

if _, err := p.SendFile(rc, file); err != nil && strings.Contains(err.Error(), "resolve home dir") {
    slog.Error("fix environment: set HOME for the daemon user", "err", err)
}

Prevention

When it happens

Trigger: Any call to SendFile or SendImage while the process has no resolvable home directory: $HOME unset/empty on Unix, or the Windows profile lookup failing (e.g. unusual service accounts).

Common situations: Daemonizing via systemd/init without setting HOME; running under docker with HOME unset or set to /nonexistent; running as a Windows service account without a loaded profile; launching from a stripped cron environment.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/f5f6a77a2f8d444f. Report an issue: GitHub.