chenhg5/cc-connect · error

claudeSession: write per-spawn prompt file: %w

Error message

claudeSession: write per-spawn prompt file: %w

What it means

newClaudeSession (agent/claudecode/session.go:315) writes the per-spawn prompt file via writeTempAppendPromptFile when a platform prompt or append prompt IS configured (the non-shared path). On failure it cancels the session context and returns 'claudeSession: write per-spawn prompt file: %w'. Session creation aborts before the claude CLI is spawned.

Source

Thrown at agent/claudecode/session.go:315

	var promptFileIsShared bool
	// Issue #1655: when a.language is non-empty, this session gets the
	// localized cc-connect system prompt. When empty (legacy callers),
	// AgentSystemPromptForLang returns the English default — same bytes as
	// the pre-PR buildAppendSystemPrompt(core.AgentSystemPrompt(), ...) call.
	if appended := buildAppendSystemPrompt(core.AgentSystemPromptForLang(lang), platformPrompt, appendSystemPrompt); appended != "" {
		if platformPrompt == "" && appendSystemPrompt == "" {
			path, err := ensureSharedSystemPromptFile(ccDataDir, appended)
			if err != nil {
				cancel()
				return nil, fmt.Errorf("claudeSession: ensure shared prompt file: %w", err)
			}
			promptFilePath = path
			promptFileIsShared = true
		} else {
			path, err := writeTempAppendPromptFile(ccDataDir, appended)
			if err != nil {
				cancel()
				return nil, fmt.Errorf("claudeSession: write per-spawn prompt file: %w", err)
			}
			promptFilePath = path
		}
		innerArgs = append(innerArgs, "--append-system-prompt-file", promptFilePath)
	}

	if effort != "" {
		innerArgs = append(innerArgs, "--effort", effort)
	}
	if maxContextTokens > 0 {
		innerArgs = append(innerArgs, "--max-context-tokens", strconv.Itoa(maxContextTokens))
	}

	// outerArgs are understood by both the wrapper and Claude CLI directly.
	var outerArgs []string
	if model != "" {
		outerArgs = append(outerArgs, "--model", model)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the wrapped cause: EMFILE → raise ulimit -n; ENOSPC → free temp space; EACCES → fix temp dir permissions.
  2. Set TMPDIR to a writable local directory (e.g. /tmp) for the cc-connect process.
  3. Retry session creation after transient resource exhaustion; per-spawn files are cleaned on failure.
  4. Check for temp-file leaks (crashed spawns leaving files) filling the temp dir, and clean <tmp>/cc-connect* leftovers.

Example fix

// before
# systemd unit
Environment=TMPDIR=/var/tmp-readonly  → write per-spawn prompt file: permission denied
// after
Environment=TMPDIR=/tmp
ExecStartPre=/usr/bin/mkdir -p /tmp && /usr/bin/chmod 1777 /tmp
Defensive patterns

Strategy: validation

Validate before calling

tmp := os.TempDir()
if st, err := os.Stat(tmp); err != nil || !st.IsDir() {
    return fmt.Errorf("TMPDIR %s invalid", tmp)
}
probe, err := os.CreateTemp(tmp, "cc-probe-*")
if err != nil {
    return fmt.Errorf("cannot create temp files in %s: %w", tmp, err)
}
probe.Close(); os.Remove(probe.Name())

Try / catch

sess, err := agent.StartSession(ctx, opts)
if err != nil && strings.Contains(err.Error(), "write per-spawn prompt file") {
    if errors.Is(err, syscall.EMFILE) { /* raise ulimit -n and retry */ }
    return nil, fmt.Errorf("temp file creation failed; check TMPDIR writability/space: %w", err)
}

Prevention

When it happens

Trigger: Calling StartSession with platformPrompt or appendSystemPrompt set, where writeTempAppendPromptFile fails at any step: temp file creation (O_CREATE fails), Chmod 0644, Close, or rename/write — causes include unwritable temp dir, chmod failure (see error 126), or fd exhaustion.

Common situations: TMPDIR pointing to a full or read-only volume; restrictive umask/ACLs or containers with noexec/non-chmod tmpfs; too many open files (EMFILE) under heavy session churn; Windows Chmod quirks.

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/02b247ef8697d9c8. Report an issue: GitHub.