WPILib ShuffleBoard Export Convert CSV Fails

Trying to record and export events from commands such as

CommandScheduler.getInstance()
        .onCommandInitialize(
            command ->
            {
                Shuffleboard.addEventMarker(
                  "Command initialized", command.getName(), EventImportance.kNormal);
            }
        );

I start and stop the Shuffleboard recording and the recording is made and works.

Attempt to export recording and convert to CSV with buttons Add Files or Add Directory fails with exceptions.

Caused by: java.lang.IllegalArgumentException: Folder parameter must be a valid folder whether I try to add files or add directory.

Log of Exceptions

Feb 21, 2023 10:20:15 AM edu.wpi.first.shuffleboard.app.Shuffleboard init
INFO: Build time: 2023-02-18T09:16:31.455508300Z
Feb 21, 2023 10:20:15 AM edu.wpi.first.shuffleboard.app.plugin.PluginLoader load
INFO: Loading plugin edu.wpi.first.shuffleboard:Base:1.3.5
Feb 21, 2023 10:20:15 AM edu.wpi.first.shuffleboard.app.plugin.PluginLoader load
INFO: Loaded plugin edu.wpi.first.shuffleboard:Base in 87ms
Feb 21, 2023 10:20:15 AM edu.wpi.first.shuffleboard.app.plugin.PluginLoader load
INFO: Loading plugin edu.wpi.first.shuffleboard:NetworkTables:2.3.1
Feb 21, 2023 10:20:15 AM edu.wpi.first.shuffleboard.app.plugin.PluginLoader load
INFO: Loaded plugin edu.wpi.first.shuffleboard:NetworkTables in 33ms
Feb 21, 2023 10:20:15 AM edu.wpi.first.shuffleboard.app.plugin.PluginLoader load
INFO: Loading plugin edu.wpi.first.shuffleboard:CameraServer:3.1.0
Feb 21, 2023 10:20:17 AM edu.wpi.first.shuffleboard.app.plugin.PluginLoader load
INFO: Loaded plugin edu.wpi.first.shuffleboard:CameraServer in 1784ms
Feb 21, 2023 10:20:18 AM edu.wpi.first.shuffleboard.app.MainWindowController initialize
INFO: Setting up plugins in the UI
Feb 21, 2023 10:20:18 AM edu.wpi.first.shuffleboard.app.Shuffleboard init
WARNING: Took 776ms to load the main FXML
Feb 21, 2023 10:20:24 AM edu.wpi.first.shuffleboard.app.Shuffleboard start
WARNING: Took 9750ms to start Shuffleboard
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:20:25 AM edu.wpi.first.shuffleboard.app.json.WidgetSaver deserialize
WARNING: Saved source type is not present, adding destroyed source(s) instead
Feb 21, 2023 10:21:33 AM edu.wpi.first.shuffleboard.app.Shuffleboard uncaughtException
WARNING: Uncaught exception on JavaFX Application Thread
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8792)
at javafx.scene.control.Button.fire(Button.java:203)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
at javafx.scene.Scene.processMouseEvent(Scene.java:1878)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at com.sun.glass.ui.View.handleMouseEvent(View.java:557)
at com.sun.glass.ui.View.notifyMouse(View.java:943)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
at jdk.internal.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1854)
… 46 more
Caused by: java.lang.IllegalArgumentException: Folder parameter must be a valid folder
at com.sun.glass.ui.CommonDialogs.convertFolder(CommonDialogs.java:239)
at com.sun.glass.ui.CommonDialogs.showFileChooser(CommonDialogs.java:191)
at com.sun.javafx.tk.quantum.QuantumToolkit.showFileChooser(QuantumToolkit.java:1718)
at javafx.stage.FileChooser.showDialog(FileChooser.java:419)
at javafx.stage.FileChooser.showOpenMultipleDialog(FileChooser.java:376)
at edu.wpi.first.shuffleboard.app.ConvertRecordingPaneController.addFiles(ConvertRecordingPaneController.java:159)
… 57 more

Feb 21, 2023 10:21:42 AM edu.wpi.first.shuffleboard.app.Shuffleboard uncaughtException
WARNING: Uncaught exception on JavaFX Application Thread
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8792)
at javafx.scene.control.Button.fire(Button.java:203)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
at javafx.scene.Scene.processMouseEvent(Scene.java:1878)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at com.sun.glass.ui.View.handleMouseEvent(View.java:557)
at com.sun.glass.ui.View.notifyMouse(View.java:943)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
at jdk.internal.reflect.GeneratedMethodAccessor12.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1854)
… 46 more
Caused by: java.lang.IllegalArgumentException: Folder parameter must be a valid folder
at com.sun.glass.ui.CommonDialogs.convertFolder(CommonDialogs.java:239)
at com.sun.glass.ui.CommonDialogs.showFolderChooser(CommonDialogs.java:227)
at com.sun.javafx.tk.quantum.QuantumToolkit.showDirectoryChooser(QuantumToolkit.java:1749)
at javafx.stage.DirectoryChooser.showDialog(DirectoryChooser.java:109)
at edu.wpi.first.shuffleboard.app.ConvertRecordingPaneController.addDirectory(ConvertRecordingPaneController.java:181)
… 57 more

Feb 21, 2023 10:21:59 AM edu.wpi.first.shuffleboard.app.MainWindowController close
INFO: Exiting app
Feb 21, 2023 10:21:59 AM edu.wpi.first.shuffleboard.app.Shuffleboard stop
INFO: Running shutdown hooks
Feb 21, 2023 10:21:59 AM edu.wpi.first.shuffleboard.app.Shuffleboard stop
INFO: Shutting down

This used to work to create a CSV file not too many days ago but not sure about which update version it was. It doesn’t work with WPILib update 2023.4.1 and I think the previous version didn’t work.

Is there a secret handshake to get a valid file or directory name? I tried all the permutations that I could think of.

You’ve probably deleted or moved the last recording file directory that was used. I don’t think there’s an easy way to reset it through shuffleboard, but if you remember the old directory name you can recreate it and then choose a different directory in the shuffleboard UI

This implies that Shuffleboard has memory somewhere. Where could that be? I recreated all the possible directories and I still can’t select a file to convert.

We tried converting a file on a PC that to my knowledge never before converted a file and it, too, said we need a valid directory.

It uses java.util.prefs.Preferences for storage, which isn’t easy to access manually (it lives in a registry entry somewhere; I forget exactly where it would be)

Odd that it doesn’t work when run on a fresh PC, though. Is there a Shuffleboard/recordings directory in the home folder?

Thanks for the info. I learned about Java Preferences.

It was a treasure hunt but I found the Windows Registry key and the directory Shuffleboard was stuck on.

When I had guessed the directory name to restore I hadn’t gone back far enough (time flies when you’re having fun).