{"record":{"id":"204df55f703c582b","repo":"m1k1o/neko","slug":"unable-to-select-files-in-dialog","errorCode":null,"errorMessage":"unable to select files in dialog","messagePattern":"unable to select files in dialog","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/desktop/filechooserdialog.go","lineNumber":58,"sourceCode":"\t\t\"key\", \"Down\",\n\t\t\"key\", \"--clearmodifiers\", \"ctrl+a\",\n\t\t\"key\", \"Return\",\n\t\t\"sleep\", fileChooserDialogLongSleep,\n\t).Run()\n\n\tif err1 != nil {\n\t\treturn err1\n\t}\n\n\t// TODO: Use native API.\n\terr2 := exec.Command(\n\t\t\"xdotool\",\n\t\t\"search\", \"--name\", fileChooserDialogName,\n\t).Run()\n\n\t// if last command didn't return error, consider dialog as still open\n\tif err2 == nil {\n\t\treturn errors.New(\"unable to select files in dialog\")\n\t}\n\n\treturn nil\n}\n\nfunc (manager *DesktopManagerCtx) CloseFileChooserDialog() {\n\tfor range fileChooserDialogCloseAttempts {\n\t\tmu.Lock()\n\n\t\tmanager.logger.Debug().Msg(\"attempting to close file chooser dialog\")\n\n\t\t// TODO: Use native API.\n\t\terr := exec.Command(\n\t\t\t\"xdotool\",\n\t\t\t\"search\", \"--name\", fileChooserDialogName, \"windowfocus\",\n\t\t).Run()\n\n\t\tif err != nil {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/m1k1o/neko/blob/b0f01cedea68893e85a3fd852c0521238c285695/server/internal/desktop/filechooserdialog.go#L40-L76","documentation":"HandleFileChooserDialog automates the native GTK 'Open File' dialog by driving it with xdotool keystrokes (typing the URI, pressing Return). After the automation sequence it re-runs `xdotool search --name \"Open File\"`; if that search still succeeds, the dialog window is still present, meaning the file selection did not complete, so this error is returned. It is a heuristic (not a native API) check that the simulated interaction failed to close the dialog.","triggerScenarios":"Calling the file-chooser upload endpoint (HandleFileChooserDialog) when the GTK 'Open File' dialog remains open after the xdotool automation: wrong window name/title match, keystrokes not delivered (window never focused), the typed URI being rejected by the dialog, autocomplete suggestions intercepting the Return key, or xdotool working but the dialog staying open for another reason.","commonSituations":"Running neko in environments where xdotool cannot reach the X display or the dialog has a localized/different title than 'Open File'; desktop environments (e.g. GNOME variants) whose file dialog behaves differently from the assumed flow; slow VMs where the fixed 0.2s/0.4s sleeps are too short; multi-monitor or focus-stealing-prevention setups that keep the dialog unfocused.","solutions":["Retry the file selection request once, then verify with IsFileChooserDialogOpened; transient focus/timing issues often succeed on a second attempt.","If the dialog is stuck, call CloseFileChooserDialog (which force-closes it with Alt+F4) and retry the upload.","Ensure xdotool is installed and the server has access to the X display (DISPLAY set, XAUTHORITY correct) so keystrokes actually reach the dialog.","Check the dialog window title matches 'Open File' (the constant fileChooserDialogName); localized desktop environments or other GTK dialogs may need the constant adjusted.","Increase reliability by running the server in a desktop environment whose file chooser matches the assumed GTK flow, or replace the xdotool hack with a native dialog API."],"exampleFix":"// before: blind retry that fails again when dialog is stuck\nif err := desktop.HandleFileChooserDialog(uri); err != nil {\n    return err\n}\n\n// after: close stuck dialog, then retry once\nif err := desktop.HandleFileChooserDialog(uri); err != nil {\n    desktop.CloseFileChooserDialog()\n    if err := desktop.HandleFileChooserDialog(uri); err != nil {\n        return err\n    }\n}","handlingStrategy":"retry","validationCode":"if !desktop.IsFileChooserDialogEnabled() {\n    return errors.New(\"file chooser dialog is not enabled on this server\")\n}\nif desktop.IsFileChooserDialogOpened() {\n    desktop.CloseFileChooserDialog() // clear a stuck dialog first\n}","typeGuard":null,"tryCatchPattern":"err := desktop.HandleFileChooserDialog(uri)\nif err != nil {\n    if err.Error() == \"unable to select files in dialog\" {\n        desktop.CloseFileChooserDialog()\n        err = desktop.HandleFileChooserDialog(uri) // one retry\n    }\n    if err != nil {\n        log.Printf(\"file selection failed: %v\", err)\n    }\n}","preventionTips":["Verify xdotool is installed and DISPLAY/XAUTHORITY are set in the container/VM.","Confirm the guest desktop's file dialog window title is 'Open File' (avoid localized desktops or adjust the constant).","Check IsFileChooserDialogEnabled before attempting file selection.","Close any already-open dialog (CloseFileChooserDialog) before issuing a new selection.","Prefer minimal desktop environments whose GTK dialog matches the assumed automation flow."],"tags":["xdotool","gtk-dialog","file-upload","desktop-automation"],"backgroundTag":"file-dialog-automation-failed","analyzedSha":"b0f01cedea68893e85a3fd852c0521238c285695","analyzedAt":"2026-09-01T10:35:56.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}