chenhg5/cc-connect · error

claudecode: project dir not found

Error message

claudecode: project dir not found

What it means

GetSessionHistory (agent/claudecode/claudecode.go:731) reads a session transcript from ~/.claude/projects/<encoded-workdir>/. When findProjectDir cannot locate the project directory for the agent's configured work_dir, it throws 'claudecode: project dir not found'. Unlike DeleteSession, it uses the agent's own a.workDir, so this usually reflects a configuration mismatch rather than a bad caller argument.

Source

Thrown at agent/claudecode/claudecode.go:731

var xmlTagRe = regexp.MustCompile(`<[^>]+>`)

func stripXMLTags(s string) string {
	return xmlTagRe.ReplaceAllString(s, "")
}

// GetSessionHistory reads the Claude Code JSONL transcript and returns user/assistant messages.
func (a *Agent) GetSessionHistory(_ context.Context, sessionID string, limit int) ([]core.HistoryEntry, error) {
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return nil, err
	}
	a.mu.RLock()
	workDir := a.workDir
	a.mu.RUnlock()
	absWorkDir, _ := filepath.Abs(workDir)
	projectDir := findProjectDir(homeDir, absWorkDir)
	if projectDir == "" {
		return nil, fmt.Errorf("claudecode: project dir not found")
	}

	path := filepath.Join(projectDir, sessionID+".jsonl")
	f, err := os.Open(path)
	if err != nil {
		return nil, fmt.Errorf("claudecode: open session file: %w", err)
	}
	defer f.Close()

	var entries []core.HistoryEntry
	scanner := bufio.NewScanner(f)
	scanner.Buffer(make([]byte, 256*1024), 256*1024)

	for scanner.Scan() {
		var raw struct {
			Type      string `json:"type"`
			Timestamp string `json:"timestamp"`
			Message   struct {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Set work_dir in the claudecode agent config to the absolute path of the project directory Claude Code was used in.
  2. Confirm ~/.claude/projects/<encoded-dir> exists (encode the abs path the way Claude Code does and stat it).
  3. Ensure the cc-connect process runs with the same HOME as the user who runs Claude Code (systemd/launchd services often run with different HOME).
  4. Check the Claude Code session actually produced a transcript in that directory before querying history.

Example fix

// before (config.toml)
[agents.claudecode]
work_dir = "~/myproject"   # relative/tilde — may not resolve as expected
# after
[agents.claudecode]
work_dir = "/home/alice/myproject"  # absolute path matching ~/.claude/projects encoding
Defensive patterns

Strategy: validation

Validate before calling

home, _ := os.UserHomeDir()
projects := filepath.Join(home, ".claude", "projects")
if st, err := os.Stat(projects); err != nil || !st.IsDir() {
    return fmt.Errorf("claude projects dir missing at %s (has claude code been used?)", projects)
}

Try / catch

entries, err := agent.GetSessionHistory(ctx, id)
if err != nil && strings.Contains(err.Error(), "project dir not found") {
    return nil, fmt.Errorf("no Claude Code history for this workspace; check work_dir config")
}

Prevention

When it happens

Trigger: Calling GetSessionHistory(ctx, sessionID) when no directory under ~/.claude/projects matches the encoded form of the agent's workDir — typically because a.workDir was never set, is relative/unexpanded, or Claude Code has never run in that directory.

Common situations: config.toml missing or containing a wrong/relative work_dir for the claudecode agent; running cc-connect with a different HOME than the one where Claude Code stored transcripts; fresh machine with no prior Claude Code usage in that directory; custom CLAUDE_CONFIG_DIR redirecting the projects dir.

Related errors


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