{"record":{"id":"06d384bf2bccf623","repo":"wavetermdev/waveterm","slug":"delete-failed-errortext","errorCode":null,"errorMessage":"Delete failed: ${errorText}","messagePattern":"Delete failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/app/view/preview/preview-directory-utils.tsx","lineNumber":129,"sourceCode":"    });\n}\n\nexport function handleFileDelete(\n    model: PreviewModel,\n    path: string,\n    recursive: boolean,\n    setErrorMsg: (msg: ErrorMsg) => void\n) {\n    fireAndForget(async () => {\n        const formattedPath = await model.formatRemoteUri(path, globalStore.get);\n        try {\n            await model.env.rpc.FileDeleteCommand(TabRpcClient, {\n                path: formattedPath,\n                recursive,\n            });\n        } catch (e) {\n            const errorText = `${e}`;\n            console.warn(`Delete failed: ${errorText}`);\n            let errorMsg: ErrorMsg;\n            if (errorText.includes(recursiveError) && !recursive) {\n                errorMsg = {\n                    status: \"Confirm Delete Directory\",\n                    text: \"Deleting a directory requires the recursive flag. Proceed?\",\n                    level: \"warning\",\n                    buttons: [\n                        {\n                            text: \"Delete Recursively\",\n                            onClick: () => handleFileDelete(model, path, true, setErrorMsg),\n                        },\n                    ],\n                };\n            } else {\n                errorMsg = {\n                    status: \"Delete Failed\",\n                    text: `${e}`,\n                };","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/frontend/app/view/preview/preview-directory-utils.tsx#L111-L147","documentation":"handleFileDelete calls the FileDeleteCommand RPC; on rejection the error is logged as 'Delete failed: <e>' and converted to an ErrorMsg. If the backend reports the directory-not-empty error (recursiveError) and recursive was not set, the UI instead asks the user to confirm a recursive delete.","triggerScenarios":"FileDeleteCommand rejects: path does not exist, permission denied, or deleting a non-empty directory without recursive=true (handled specially as 'Confirm Delete Directory').","commonSituations":"Deleting a populated directory without the recursive flag; deleting on a read-only mount or without permissions; a stale preview entry for a file already removed elsewhere.","solutions":["If prompted 'Deleting a directory requires the recursive flag', confirm to retry with recursive=true","Check the logged error text for the exact backend reason (permissions, not found)","Refresh the preview to clear stale entries, then retry","Verify permissions on the target path or parent directory"],"exampleFix":"// before\nawait model.env.rpc.FileDeleteCommand(TabRpcClient, { path: formattedPath, recursive });\n// after\nif (isDir && !recursive) {\n    // prompt user first\n    recursive = await confirmRecursiveDelete(formattedPath);\n}\nawait model.env.rpc.FileDeleteCommand(TabRpcClient, { path: formattedPath, recursive });","handlingStrategy":"try-catch","validationCode":"// before deleting a directory, require explicit recursive consent\nif (isDirectory(path) && !recursive) {\n    recursive = await confirm('Delete directory and all contents?');\n}\nif (!(await uriExists(formattedPath))) return; // nothing to delete","typeGuard":"function isRecursiveRequiredError(errorText: string, recursiveError: string): boolean {\n    return errorText.includes(recursiveError) && !recursive;\n}","tryCatchPattern":"try {\n    await model.env.rpc.FileDeleteCommand(TabRpcClient, { path: formattedPath, recursive });\n} catch (e) {\n    const errorText = `${e}`;\n    console.warn(`Delete failed: ${errorText}`);\n    if (errorText.includes(recursiveError) && !recursive) {\n        setErrorMsg({ status: 'Confirm Delete Directory', text: 'Deleting a directory requires the recursive flag. Proceed?', level: 'warning' });\n    } else {\n        setErrorMsg({ status: 'Delete Failed', text: errorText });\n    }\n}","preventionTips":["Prompt for confirmation before recursive directory deletes","Handle the recursiveError case as a retry-with-flag flow, not a hard failure","Refresh the preview to avoid deleting stale paths","Check permissions on the target before invoking FileDeleteCommand"],"tags":["rpc","filesystem","delete","preview"],"backgroundTag":"file-delete-rpc-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}