chenhg5/cc-connect · error

claudecode: create usage temp dir: %w

Error message

claudecode: create usage temp dir: %w

What it means

runClaudeUsageProbe creates a temporary working directory (os.MkdirTemp with pattern "cc-connect-claude-usage-*") to run an isolated claude usage probe. This error wraps the os.MkdirTemp failure — the temp-dir root is unwritable, the pattern is invalid (practically never), or the OS ran out of resources.

Source

Thrown at agent/claudecode/claude_usage.go:67

func (a *Agent) GetUsage(ctx context.Context) (*core.UsageReport, error) {
	if _, err := exec.LookPath("claude"); err != nil {
		return nil, fmt.Errorf("claudecode: 'claude' CLI not found in PATH")
	}

	screen, err := a.runClaudeUsageProbe(ctx)
	if err != nil {
		return nil, err
	}
	return parseClaudeUsageReport(screen, time.Now())
}

func (a *Agent) runClaudeUsageProbe(ctx context.Context) (string, error) {
	probeCtx, cancel := context.WithCancel(ctx)
	defer cancel()

	workDir, err := os.MkdirTemp("", "cc-connect-claude-usage-*")
	if err != nil {
		return "", fmt.Errorf("claudecode: create usage temp dir: %w", err)
	}
	defer os.RemoveAll(workDir)

	args := []string{
		"--tools", "",
		"--permission-mode", "plan",
		"--no-chrome",
	}
	cmd := exec.CommandContext(probeCtx, "claude", args...)
	cmd.Dir = workDir

	env := filterEnv(os.Environ(), "CLAUDECODE")
	env = append(env, "DISABLE_TELEMETRY=true")
	env = append(env, "DISABLE_COST_WARNINGS=true")
	if extra := a.usageProbeEnv(); len(extra) > 0 {
		env = core.MergeEnv(env, extra)
	}
	cmd.Env = env

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check TMPDIR for the cc-connect process (`cat /proc/<pid>/environ | tr '\0' '\n' | grep TMPDIR`) and ensure it exists and is writable by the service user
  2. Free disk space / fix filesystem permissions on the temp root
  3. Set TMPDIR explicitly to a safe writable location in the daemon environment (e.g. TMPDIR=/var/tmp/cc-connect with correct ownership)
  4. If running in a container, mount a writable tmpfs at /tmp
Defensive patterns

Strategy: try-catch

Validate before calling

tmp := os.TempDir()
if fi, err := os.Stat(tmp); err != nil || !fi.IsDir() { return fmt.Errorf("TMPDIR %s unusable", tmp) }
probe, err := os.MkdirTemp(tmp, ".cc-connect-write-test-*"); if err == nil { os.Remove(probe) } else { return err }

Type guard

func tempDirWritable() bool { d, err := os.MkdirTemp("", "cc-connect-probe-*"); if err != nil { return false }; os.Remove(d); return true }

Try / catch

screen, err := runClaudeUsageProbe(ctx)
if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && strings.Contains(err.Error(), "create usage temp dir") {
        log.Errorf("temp dir creation failed: %v (check TMPDIR permissions/disk space)", pe)
    }
    return err
}

Prevention

When it happens

Trigger: GetUsage → runClaudeUsageProbe → os.MkdirTemp("", "cc-connect-claude-usage-*") fails with a *PathError: TMPDIR points to a nonexistent/unwritable directory, disk full, or the process lacks permission to create directories in the temp root.

Common situations: Hardened TMPDIR with restrictive permissions for the service user; TMPDIR set to a path that was deleted; read-only filesystem or full disk on the host running the daemon; container with a tiny/noexec tmpfs.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


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