{"record":{"id":"2c7e9061c9786682","repo":"larksuite/cli","slug":"create-directory-w","errorCode":null,"errorMessage":"create directory: %w","messagePattern":"create directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/response.go","lineNumber":220,"sourceCode":"}\n\n// ── File saving ──\n\n// SaveResponse writes an API response body to the given outputPath and returns metadata.\n// It delegates to FileIO.Save for path validation and atomic write; fio must not be nil.\nfunc SaveResponse(fio fileio.FileIO, resp *larkcore.ApiResp, outputPath string) (map[string]interface{}, error) {\n\tresult, err := fio.Save(outputPath, fileio.SaveOptions{\n\t\tContentType:   resp.Header.Get(\"Content-Type\"),\n\t\tContentLength: int64(len(resp.RawBody)),\n\t}, bytes.NewReader(resp.RawBody))\n\tif err != nil {\n\t\tvar me *fileio.MkdirError\n\t\tvar we *fileio.WriteError\n\t\tswitch {\n\t\tcase errors.Is(err, fileio.ErrPathValidation):\n\t\t\treturn nil, fmt.Errorf(\"unsafe output path: %w\", err)\n\t\tcase errors.As(err, &me):\n\t\t\treturn nil, fmt.Errorf(\"create directory: %w\", err)\n\t\tcase errors.As(err, &we):\n\t\t\treturn nil, fmt.Errorf(\"cannot write file: %w\", err)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"cannot write file: %w\", err)\n\t\t}\n\t}\n\n\tresolvedPath, err := fio.ResolvePath(outputPath)\n\tif err != nil || resolvedPath == \"\" {\n\t\tresolvedPath = outputPath\n\t}\n\treturn map[string]interface{}{\n\t\t\"saved_path\":   resolvedPath,\n\t\t\"size_bytes\":   result.Size(),\n\t\t\"content_type\": resp.Header.Get(\"Content-Type\"),\n\t}, nil\n}\n","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/client/response.go#L202-L238","documentation":"SaveResponse wraps failures from the FileIO Mkdir call when it needs to create the output directory for a saved API response. If the underlying error is a fileio.MkdirError, it is re-wrapped as 'create directory: %w' with the original cause preserved. This signals that the output path's parent directory could not be created, distinct from path-validation failures ('unsafe output path') and write failures ('cannot write file').","triggerScenarios":"Calling SaveResponse (directly or via HandleResponse/saveAndPrint) with an outputPath whose directory cannot be created by the FileIO layer — e.g. permission denied on the parent, a non-directory file occupying the path segment, or filesystem errors on the host where FileIO runs.","commonSituations":"Saving to a path under a read-only directory, an output path colliding with an existing regular file (e.g. .../out exists as a file so .../out/part.json can't get a dir), sandboxed/CI filesystems denying writes, or a remote/scoped FileIO backend refusing mkdir outside its allowed tree.","solutions":["Check permissions on the nearest existing ancestor of outputPath and create the directory manually (mkdir -p) or run with write access","Verify no regular file exists at the directory segment of outputPath; rename or remove it","If running in a scoped/sandboxed environment, save inside the FileIO-allowed tree (e.g. use runtime.ResolveSavePath)","Inspect the wrapped cause (%v / errors.Unwrap) for the exact OS error and act on it"],"exampleFix":"// before\nclient.SaveResponse(resp, \"/root/outputs/response.json\") // permission denied\n// after\nclient.SaveResponse(resp, filepath.Join(os.TempDir(), \"lark-outputs\", \"response.json\"))","handlingStrategy":"try-catch","validationCode":"if st, err := os.Stat(filepath.Dir(outputPath)); err == nil && !st.IsDir() {\n    return fmt.Errorf(\"%s exists and is not a directory\", filepath.Dir(outputPath))\n}","typeGuard":"var me *fileio.MkdirError\nif errors.As(err, &me) { /* handle mkdir failure specifically */ }","tryCatchPattern":"path, err := client.SaveResponse(resp, outputPath)\nif err != nil {\n    var me *fileio.MkdirError\n    if strings.HasPrefix(err.Error(), \"create directory:\") || errors.As(err, &me) {\n        // fix directory creation: permissions, existing file, allowed tree\n    }\n    return err\n}","preventionTips":["Pre-create the output directory with os.MkdirAll before calling SaveResponse","Save inside the FileIO-allowed/configured tree (runtime.ResolveSavePath)","Never point outputPath at a segment occupied by a regular file","Check write permissions on the target directory in CI/sandbox environments"],"tags":["filesystem","mkdir","io"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}