{"record":{"id":"40b55ad55e8b9ef8","repo":"charmbracelet/crush","slug":"error-reading-file-w","errorCode":null,"errorMessage":"error reading file: %w","messagePattern":"error reading file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/view.go","lineNumber":242,"sourceCode":"\t\t\t\t// it identifies a supported image format.\n\t\t\t\tmimeType = sniffImageMimeType(imageData, mimeType)\n\n\t\t\t\treturn fantasy.NewImageResponse(imageData, mimeType), nil\n\t\t\t}\n\n\t\t\t// Read the file content\n\t\t\tmaxContentSize := MaxViewSize\n\t\t\tif isSkillFile {\n\t\t\t\tmaxContentSize = 0\n\t\t\t}\n\t\t\tcontent, hasMore, err := readTextFile(filePath, params.Offset, params.Limit, maxContentSize)\n\t\t\tif err != nil {\n\t\t\t\tvar tooLarge contentTooLargeError\n\t\t\t\tif errors.As(err, &tooLarge) {\n\t\t\t\t\treturn fantasy.NewTextErrorResponse(fmt.Sprintf(\"Content section is too large (%d bytes). Maximum size is %d bytes\",\n\t\t\t\t\t\ttooLarge.Size, tooLarge.Max)), nil\n\t\t\t\t}\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"error reading file: %w\", err)\n\t\t\t}\n\t\t\tif !utf8.ValidString(content) {\n\t\t\t\treturn fantasy.NewTextErrorResponse(\"File content is not valid UTF-8\"), nil\n\t\t\t}\n\n\t\t\topenInLSPs(ctx, lspManager, filePath)\n\t\t\twaitForLSPDiagnostics(ctx, lspManager, filePath, 300*time.Millisecond)\n\t\t\toutput := \"<file>\\n\"\n\t\t\toutput += addLineNumbers(content, params.Offset+1)\n\n\t\t\tif hasMore {\n\t\t\t\toutput += fmt.Sprintf(\"\\n\\n(File has more lines. Use 'offset' parameter to read beyond line %d)\",\n\t\t\t\t\tparams.Offset+len(strings.Split(content, \"\\n\")))\n\t\t\t}\n\t\t\toutput += \"\\n</file>\\n\"\n\t\t\toutput += getDiagnostics(filePath, lspManager)\n\t\t\tfiletracker.RecordRead(ctx, sessionID, filePath)\n","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/view.go#L224-L260","documentation":"readTextFile failed while reading the text file content, and the error was not the handled contentTooLargeError (which returns a friendly size-limit message instead). The wrapped cause could be an I/O error, a read race on a file that changed, or a limit/offset seeking issue inside readTextFile.","triggerScenarios":"I/O errors mid-read (failing disk, dropped network mount); the file being truncated/replaced while reading; internal errors from the offset/limit reading logic other than the too-large sentinel.","commonSituations":"Log files being actively rotated/rewritten while viewed; removable or network media disconnecting; files on failing hardware; extremely large files hitting other reader constraints.","solutions":["Inspect the wrapped cause to identify the OS-level problem","Retry the read — transient I/O and race conditions often resolve","For actively-written files, snapshot first (cp) and view the copy","Check disk health / remount network shares if errors persist"],"exampleFix":"// before\nview /var/log/app.log  // log rotated mid-read\n// after\ncp /var/log/app.log /tmp/app.log.snapshot && view /tmp/app.log.snapshot","handlingStrategy":"retry","validationCode":"f, err := os.Open(path)\nif err != nil {\n    return fmt.Errorf(\"file %q unreadable: %w\", path, err)\n}\nf.Close()","typeGuard":"func readableFile(path string) bool {\n    f, err := os.Open(path)\n    if err != nil { return false }\n    f.Close()\n    return true\n}","tryCatchPattern":"var tooLarge contentTooLargeError\nif !errors.As(err, &tooLarge) { // too-large is handled as a text response already\n    var pe *fs.PathError\n    if errors.As(err, &pe) {\n        // I/O problem: retry or snapshot the file and re-read\n    }\n}","preventionTips":["Snapshot actively-written files (logs) before viewing them","Retry transient I/O failures, especially on network mounts","Check disk health if read errors recur on the same volume","Use offset/limit within the file's actual size bounds"],"tags":["filesystem","io","read-failure"],"backgroundTag":"file-read-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}