{"record":{"id":"0fa2f29fa8910746","repo":"charmbracelet/crush","slug":"error-resolving-working-directory-w","errorCode":null,"errorMessage":"error resolving working directory: %w","messagePattern":"error resolving working directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/view.go","lineNumber":118,"sourceCode":"\t\tviewDescription(),\n\t\tfunc(ctx context.Context, params ViewParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) {\n\t\t\tif params.FilePath == \"\" {\n\t\t\t\treturn fantasy.NewTextErrorResponse(\"file_path is required\"), nil\n\t\t\t}\n\n\t\t\t// Handle builtin skill files (crush: prefix).\n\t\t\tif strings.HasPrefix(params.FilePath, skills.BuiltinPrefix) {\n\t\t\t\tresp, err := readBuiltinFile(params, skillTracker)\n\t\t\t\treturn resp, err\n\t\t\t}\n\n\t\t\t// Handle relative paths\n\t\t\tfilePath := filepathext.SmartJoin(workingDir, params.FilePath)\n\n\t\t\t// Check if file is outside working directory and request permission if needed\n\t\t\tabsWorkingDir, err := filepath.Abs(workingDir)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"error resolving working directory: %w\", err)\n\t\t\t}\n\n\t\t\tabsFilePath, err := filepath.Abs(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"error resolving file path: %w\", err)\n\t\t\t}\n\n\t\t\trelPath, err := filepath.Rel(absWorkingDir, absFilePath)\n\t\t\tisOutsideWorkDir := err != nil || strings.HasPrefix(relPath, \"..\")\n\t\t\tisSkillFile := isInSkillsPath(absFilePath, skillsPaths)\n\n\t\t\tsessionID := GetSessionFromContext(ctx)\n\t\t\tif sessionID == \"\" {\n\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"session ID is required for accessing files outside working directory\")\n\t\t\t}\n\n\t\t\t// Request permission for files outside working directory, unless it's a skill file.\n\t\t\tif isOutsideWorkDir && !isSkillFile {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/view.go#L100-L136","documentation":"filepath.Abs(workingDir) failed while resolving the view tool's working directory to an absolute path. filepath.Abs rarely fails (it uses os.Getwd when the path is relative), so this usually means the current working directory is unavailable — e.g. the process's cwd was deleted.","triggerScenarios":"The tool was constructed with a relative workingDir and the process's current working directory no longer exists or cannot be stat'd, making os.Getwd inside filepath.Abs fail.","commonSituations":"Working directory removed while the process runs (deleted tmpdir, unmounted volume); launching the process from a since-deleted directory; race with external tooling cleaning up directories.","solutions":["Pass an absolute path as workingDir to NewViewTool so os.Getwd is never needed","Ensure the process's original cwd still exists for the process lifetime","Restart the process from a valid directory","Recreate the deleted directory"],"exampleFix":"// before\nNewViewTool(lsp, perms, ft, st, \"./\", skillPaths...) // relies on os.Getwd\n// after\nabs, _ := filepath.Abs(\"./\") // resolve once at startup, while cwd is valid\nNewViewTool(lsp, perms, ft, st, abs, skillPaths...)","handlingStrategy":"validation","validationCode":"if !filepath.IsAbs(workingDir) {\n    if _, err := os.Getwd(); err != nil {\n        return fmt.Errorf(\"cannot resolve relative workingDir: %w\", err)\n    }\n}","typeGuard":"func isUsableDir(dir string) bool {\n    abs, err := filepath.Abs(dir)\n    return err == nil && func() bool { st, err := os.Stat(abs); return err == nil && st.IsDir() }()\n}","tryCatchPattern":"var pe *fs.PathError\nif errors.As(err, &pe) {\n    // cwd deleted: recreate it or restart process from a valid directory\n}","preventionTips":["Always pass an absolute workingDir to NewViewTool","Avoid deleting a process's cwd while it runs (watch tmpdir cleanup tools)","Start the process from a stable directory"],"tags":["go","filesystem","path-resolution"],"backgroundTag":"path-resolution-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}