chenhg5/cc-connect · warning

wps-agentspace: SendImage: %w

Error message

wps-agentspace: SendImage: %w

What it means

SendImage wraps any failure from saveAttachment (home-dir resolution, mkdir, or file write) into "wps-agentspace: SendImage: %w". Because the platform has no image-upload API surface here, it persists the image to ~/.cc-connect/attachments/ and sends a text notice with the local path; this error means that persistence step failed, so no message was sent to the chat.

Source

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

		return fmt.Errorf("wps-agentspace: SendImage: invalid reply context type %T", replyCtx)
	}

	name := img.FileName
	if name == "" {
		ext := ".png"
		if strings.HasPrefix(img.MimeType, "image/jpeg") {
			ext = ".jpg"
		} else if strings.HasPrefix(img.MimeType, "image/gif") {
			ext = ".gif"
		} else if strings.HasPrefix(img.MimeType, "image/webp") {
			ext = ".webp"
		}
		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)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the wrapped cause: errors.Is(err, os.ErrPermission), errors.Is(err, fs.ErrNotExist), or inspect via errors.Unwrap to see if it is "resolve home dir", "mkdir", or "write".
  2. Ensure $HOME is set and writable by the daemon user; for systemd units add Environment=HOME=/var/lib/cc-connect and make that directory writable.
  3. Manually verify mkdir -p ~/.cc-connect/attachments succeeds as the daemon user; fix permissions (chown/chmod) if not.
  4. Free disk space or raise quota if the cause is a write failure (ENOSPC).

Example fix

// before (systemd unit, HOME unset for service user)
[Service]
User=ccconnect
ExecStart=/usr/local/bin/cc-connect
// after
[Service]
User=ccconnect
Environment=HOME=/var/lib/cc-connect
ExecStart=/usr/local/bin/cc-connect
Defensive patterns

Strategy: try-catch

Validate before calling

home, err := os.UserHomeDir()
if err != nil {
    return fmt.Errorf("cannot send image: home dir unresolvable: %w", err)
}
dir := filepath.Join(home, ".cc-connect", "attachments")
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
    return fmt.Errorf("attachments dir %s missing", dir)
}

Try / catch

if err := p.SendImage(rc, img); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) {
        slog.Error("image save failed on path", "op", pe.Op, "path", pe.Path, "err", pe.Err)
    } else {
        slog.Error("image send failed", "err", err)
    }
}

Prevention

When it happens

Trigger: Calling SendImage when os.UserHomeDir() fails, ~/.cc-connect/attachments cannot be created (permissions, read-only $HOME, full disk), or os.WriteFile fails (disk quota, name collision with a directory). All underlying errors are joined via %w, so errors.Is/As unwrapping works.

Common situations: Running the cc-connect daemon as a system service whose $HOME is unset or points to a non-writable directory (e.g. systemd with no HOME=, or /nonexistent); read-only root filesystems in containers; disk full after large attachment uploads.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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