{"record":{"id":"ed35d6b6a5c8f8e4","repo":"charmbracelet/crush","slug":"permission-request-failed-w-ed35d6","errorCode":null,"errorMessage":"permission request failed: %w","messagePattern":"permission request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/agent/tools/lsp_replace_symbol.go","lineNumber":147,"sourceCode":"\t\t\t}\n\n\t\t\tnewContent := strings.Join(newLines, \"\\n\")\n\n\t\t\tsessionID := GetSessionFromContext(ctx)\n\t\t\tif sessionID != \"\" && permissions != nil {\n\t\t\t\tgranted, err := permissions.Request(ctx, permission.CreatePermissionRequest{\n\t\t\t\t\tSessionID:   sessionID,\n\t\t\t\t\tPath:        params.FilePath,\n\t\t\t\t\tToolName:    ReplaceSymbolToolName,\n\t\t\t\t\tDescription: fmt.Sprintf(\"%s symbol '%s' in %s\", action, params.Symbol, params.FilePath),\n\t\t\t\t\tParams: ReplaceSymbolPermissionsParams{\n\t\t\t\t\t\tFilePath:   params.FilePath,\n\t\t\t\t\t\tOldContent: string(content),\n\t\t\t\t\t\tNewContent: newContent,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fantasy.ToolResponse{}, fmt.Errorf(\"permission request failed: %w\", err)\n\t\t\t\t}\n\t\t\t\tif !granted {\n\t\t\t\t\treturn NewPermissionDeniedResponse(), nil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif files != nil && sessionID != \"\" {\n\t\t\t\tif _, err := files.CreateVersion(ctx, sessionID, params.FilePath, string(content)); err != nil {\n\t\t\t\t\tslog.Warn(\"Failed to create file version before replace\", \"path\", params.FilePath, \"error\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif err := os.WriteFile(params.FilePath, []byte(newContent), 0o644); 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\tif filetracker != nil && sessionID != \"\" {\n\t\t\t\tfiletracker.RecordRead(ctx, sessionID, params.FilePath)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/agent/tools/lsp_replace_symbol.go#L129-L165","documentation":"This error is returned when the tool's permission request to the configured permission service fails (the Request call itself returned an error, e.g. transport/handler failure), distinct from a denial which returns NewPermissionDeniedResponse(). The wrapped error indicates the permission workflow could not complete, so the file replacement is aborted before any write.","triggerScenarios":"Calling lsp_replace_symbol on a file requiring approval when the permissions.Request call errors: permission provider misconfigured, the UI/handler session is unavailable or closed, or the permission service's underlying request channel fails.","commonSituations":"Running headless where no permission approver is attached; the session was cancelled while the prompt was pending; a custom permission provider returned an error; permission timeouts in non-interactive environments.","solutions":["Inspect the wrapped error to identify the permission provider failure.","Attach a working permission handler/approver for the session (interactive UI or configured auto-allow rules).","Add an allow-list entry for the edit permission in crush config so no interactive request is needed.","Retry the operation once a permission handler is available."],"exampleFix":"// before\n// no config; every edit triggers a permission request that fails headless\n// after\n// crushrc\npermissions {\n\tallow [\"edit\"]\n}","handlingStrategy":"try-catch","validationCode":"// ensure a permission handler exists before running the tool\nif perms == nil || !perms.HasHandler() {\n\treturn errors.New(\"no permission handler attached for this session\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := tool.Run(ctx, call)\nif err != nil && strings.Contains(err.Error(), \"permission request failed\") {\n\t// fall back to auto-allowed config or surface to user\n\treturn handlePermissionFailure(err)\n}","preventionTips":["Configure allow-list permissions in crushrc for trusted edit operations.","Run interactively (with UI approver attached) for permission-gated tools.","Don't cancel sessions while permission prompts are pending.","Test permission flows in the same environment where the tool will run."],"tags":["permissions","go","tools"],"backgroundTag":"permission-request-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}