{"record":{"id":"e6a46500ca1d230f","repo":"chenhg5/cc-connect","slug":"pi-read-history-w","errorCode":null,"errorMessage":"pi: read history: %w","messagePattern":"pi: read history: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/pi/pi.go","lineNumber":673,"sourceCode":"\n\t\tvar text string\n\t\tcontent, _ := msg[\"content\"].([]any)\n\t\tfor _, c := range content {\n\t\t\titem, _ := c.(map[string]any)\n\t\t\tif item != nil {\n\t\t\t\tif t, ok := item[\"text\"].(string); ok && t != \"\" {\n\t\t\t\t\ttext = t\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif text == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tall = append(all, core.HistoryEntry{Role: role, Content: text})\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"pi: read history: %w\", err)\n\t}\n\n\tif limit > 0 && len(all) > limit {\n\t\tall = all[len(all)-limit:]\n\t}\n\treturn all, nil\n}\n","sourceCodeStart":655,"sourceCodeEnd":681,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/pi/pi.go#L655-L681","documentation":"readPiHistory streams a pi session JSONL file with a bufio.Scanner and appends HistoryEntry items; if scanner.Err() reports an I/O failure mid-read (not EOF), it wraps the error as 'pi: read history'. Called by GetSessionHistory when fetching past conversation turns.","triggerScenarios":"Calling GetSessionHistory for a session whose JSONL file exists but becomes unreadable during scanning: I/O errors, file deleted/truncated mid-read, or device errors. Note: an overly long JSONL line exceeding bufio.Scanner's default 64KB token limit also surfaces as a scanner error here.","commonSituations":"Very long agent messages/tool outputs producing single JSONL lines >64KB (bufio.ErrTooLong); network-mounted home directories dropping connections mid-read; files rotated by cleanup jobs while history is being fetched.","solutions":["If the cause is bufio.ErrTooLong (very large single line), the scanner buffer must be enlarged in the adapter (scanner.Buffer with a larger max) — report/patch, since callers cannot fix it externally.","Re-run GetSessionHistory; transient I/O errors on network filesystems often resolve on retry.","Verify the session file still exists and is readable at the path findSessionFile resolved.","Check disk/FS health if errors persist (dmesg, mount status)."],"exampleFix":"// caller-side retry before\nentries, err := agent.GetSessionHistory(ctx, sessionID, 50)\nif err != nil {\n    return err\n}\n// after\nentries, err := agent.GetSessionHistory(ctx, sessionID, 50)\nif err != nil {\n    time.Sleep(500 * time.Millisecond)\n    entries, err = agent.GetSessionHistory(ctx, sessionID, 50)\n    if err != nil {\n        return fmt.Errorf(\"get history: %w\", err)\n    }\n}","handlingStrategy":"retry","validationCode":"sessFile := findSessionFile(sessDir, sessionID)\nf, err := os.Open(sessFile)\nif err != nil {\n    return fmt.Errorf(\"history file unreadable: %w\", err)\n}\nf.Close()","typeGuard":null,"tryCatchPattern":"entries, err := agent.GetSessionHistory(ctx, sessionID, limit)\nif err != nil {\n    select {\n    case <-time.After(500 * time.Millisecond):\n        entries, err = agent.GetSessionHistory(ctx, sessionID, limit)\n    case <-ctx.Done():\n        return ctx.Err()\n    }\n}","preventionTips":["Retry transient history reads once before surfacing the error to the user.","Watch for bufio.ErrTooLong with very large tool outputs — enlarge the scanner buffer in the adapter if it recurs.","Don't rotate/clean pi session files while the daemon is serving history for them."],"tags":["go","file-io","history","scanner"],"backgroundTag":"file-read-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}