{"record":{"id":"e9b4fb618df098b7","repo":"charmbracelet/crush","slug":"failed-to-create-output-file-w","errorCode":null,"errorMessage":"failed to create output file: %w","messagePattern":"failed to create output file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/download.go","lineNumber":145,"sourceCode":"\t\t\tresp, err := client.Do(req)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"failed to download from URL: %w\", err)\n\t\t\t}\n\t\t\tdefer resp.Body.Close()\n\n\t\t\tif resp.StatusCode != http.StatusOK {\n\t\t\t\treturn fantasy.NewTextErrorResponse(fmt.Sprintf(\"Request failed with status code: %d\", resp.StatusCode)), nil\n\t\t\t}\n\n\t\t\t// Create parent directories if they don't exist\n\t\t\tif err := os.MkdirAll(filepath.Dir(filePath), 0o755); err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"failed to create parent directories: %w\", err)\n\t\t\t}\n\n\t\t\t// Create the output file\n\t\t\toutFile, err := os.Create(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"failed to create output file: %w\", err)\n\t\t\t}\n\t\t\tdefer outFile.Close()\n\n\t\t\t// Copy data without an explicit size limit.\n\t\t\t// The overall download is still constrained by the HTTP client's timeout\n\t\t\t// and any upstream server limits.\n\t\t\tbytesWritten, err := io.Copy(outFile, resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"failed to write file: %w\", err)\n\t\t\t}\n\n\t\t\tcontentType := resp.Header.Get(\"Content-Type\")\n\t\t\tresponseMsg := fmt.Sprintf(\"Successfully downloaded %d bytes to %s\", bytesWritten, relPath)\n\t\t\tif contentType != \"\" {\n\t\t\t\tresponseMsg += fmt.Sprintf(\" (Content-Type: %s)\", contentType)\n\t\t\t}\n\n\t\t\treturn fantasy.NewTextResponse(responseMsg), nil","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/download.go#L127-L163","documentation":"os.Create failed when opening/creating the destination file for the download. Parent directories were already created successfully, so this is specific to the final path component: the wrapped OS error gives the reason (permission denied, is-a-directory, too many open files, disk full at open time).","triggerScenarios":"filePath itself is an existing directory, the process lacks write permission on the containing directory, the path exceeds NAME_MAX, or the process hit its file-descriptor limit.","commonSituations":"file_path names an existing directory; downloading into a directory without write access; downloading many files concurrently exhausting ulimit -n; filename with illegal characters (e.g. '/' embedded, NUL).","solutions":["Ensure file_path is not an existing directory and is a valid filename","Check write permission on the target directory","Close leaked file handles if fd limits are involved (ulimit -n)","Check the wrapped error (EISDIR, EACCES, ENAMETOOLONG) and correct the path accordingly"],"exampleFix":"// before\nfile_path: \"dist\"            // dist is a directory\n// after\nfile_path: \"dist/app.tar.gz\"","handlingStrategy":"validation","validationCode":"if fi, err := os.Stat(target); err == nil && fi.IsDir() {\n    return fmt.Errorf(\"%s is a directory; pick a file name\", target)\n}\nif f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY, 0o644); err != nil {\n    return fmt.Errorf(\"cannot create %s: %v\", target, err)\n} else { f.Close() }","typeGuard":null,"tryCatchPattern":"outFile, err := os.Create(filePath)\nif err != nil {\n    switch {\n    case errors.Is(err, fs.ErrPermission):\n        return fmt.Errorf(\"no permission to create %s\", filePath)\n    case errors.Is(err, syscall.EISDIR):\n        return fmt.Errorf(\"%s is a directory\", filePath)\n    default:\n        return err\n    }\n}","preventionTips":["Don't pass an existing directory as file_path","Use valid, reasonably short filenames","Watch fd limits when creating many files concurrently","Ensure the target directory grants write permission"],"tags":["filesystem","file-create","permissions"],"backgroundTag":"file-open-permission-denied","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}