[GH-ISSUE #18] FR: Hide apps for users vs deleting from config.toml? #12

Closed
opened 2026-10-15 12:54:19 +00:00 by bsakaguchi · 11 comments
Owner

Originally created by @Hukuma1 on GitHub (May 31, 2026).
Original GitHub issue: https://github.com/games-on-whales/wolf-den/issues/18

I have 3 users. I am trying to decide which user gets access to which app. I drag over an app here, or an app there and hit save. However, this seems to completely remove the apps from the main app list. If my first user only needs RetroArch access and my other users need additional apps, I am stuck as Wolf-Den seems to completely delete the other apps from the config file altogether? Is this the intended behavior?

Can we maybe keep the apps in the main list and hide them instead? Or can you at least make it easy to re-add removed apps? I know there's an add app field, but I think it's very advanced and silly for me to go and re-code the container by hand. Perhaps Wolf-Den can keep an apps.toml or something as a backup of the default config apps and re-populate from there?

Originally created by @Hukuma1 on GitHub (May 31, 2026). Original GitHub issue: https://github.com/games-on-whales/wolf-den/issues/18 I have 3 users. I am trying to decide which user gets access to which app. I drag over an app here, or an app there and hit save. However, this seems to completely remove the apps from the main app list. If my first user only needs RetroArch access and my other users need additional apps, I am stuck as Wolf-Den seems to completely delete the other apps from the config file altogether? Is this the intended behavior? Can we maybe keep the apps in the main list and hide them instead? Or can you at least make it easy to re-add removed apps? I know there's an add app field, but I think it's very advanced and silly for me to go and re-code the container by hand. Perhaps Wolf-Den can keep an `apps.toml` or something as a backup of the default config apps and re-populate from there?
Author
Owner

@Skerga commented on GitHub (May 31, 2026):

this will be addressed in the upcoming PR #13, unused app should then be correctly saved for later re-adding. You can also try out these changes by using the ghcr.io/games-on-whales/wolf-den:dev-improvements image for wolf-den

<!-- gh-comment-id:4586965685 --> @Skerga commented on GitHub (May 31, 2026): this will be addressed in the upcoming PR #13, unused app should then be correctly saved for later re-adding. You can also try out these changes by using the `ghcr.io/games-on-whales/wolf-den:dev-improvements` image for wolf-den
Author
Owner

@Hukuma1 commented on GitHub (May 31, 2026):

You rock. Thank you. Keep up the great work!

<!-- gh-comment-id:4586973490 --> @Hukuma1 commented on GitHub (May 31, 2026): You rock. Thank you. Keep up the great work!
Author
Owner

@Hukuma1 commented on GitHub (May 31, 2026):

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://[::]:8080
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app
fail: Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery[7]
      An exception was thrown while deserializing the token.
      Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted.
       ---> System.Security.Cryptography.CryptographicException: The key {dec2da64-a204-4e83-ade3-c5481523483f} was not found in the key ring. For more information go to https://aka.ms/aspnet/dataprotectionwarning
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
         at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
         --- End of inner exception stack trace ---
         at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
         at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext)
warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
      Unhandled exception rendering component: Could not deserialize the response body stream as GamesOnWhales.AppListResponse.
      
      Status: 200
      Response: 
      
      HTTP Response: 
      
      
      
      GamesOnWhales.ApiException: Could not deserialize the response body stream as GamesOnWhales.AppListResponse.
      
      Status: 200
      Response: 
      
       ---> Newtonsoft.Json.JsonSerializationException: Required property 'name' not found in JSON. Path 'apps[1].runner', line 1, position 7005.
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EndProcessProperty(Object newObject, JsonReader reader, JsonObjectContract contract, Int32 initialDepth, JsonProperty property, PropertyPresence presence, Boolean setDefaultValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
         at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
         at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
         at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
         at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken)
         --- End of inner exception stack trace ---
         at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken)
         at GamesOnWhales.GeneratedApiClient.AppsAsync(CancellationToken cancellationToken)
         at GamesOnWhales.WolfApi.GetAppsAsync()
         at WolfLeash.Components.Pages.Apps.Show.OnInitializedAsync() in /src/WolfLeash/Components/Pages/Apps/Show.razor:line 48
         at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'bVs1W2FZDyYO2w0BekiQqash0foL0nqmsGMeRe6uwCE'.
      HTTP Response: 
      
      
      
      GamesOnWhales.ApiException: Could not deserialize the response body stream as GamesOnWhales.AppListResponse.
      
      Status: 200
      Response: 
      
       ---> Newtonsoft.Json.JsonSerializationException: Required property 'name' not found in JSON. Path 'apps[1].runner', line 1, position 7005.
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EndProcessProperty(Object newObject, JsonReader reader, JsonObjectContract contract, Int32 initialDepth, JsonProperty property, PropertyPresence presence, Boolean setDefaultValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
         at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
         at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
         at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
         at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken)
         --- End of inner exception stack trace ---
         at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken)
         at GamesOnWhales.GeneratedApiClient.AppsAsync(CancellationToken cancellationToken)
         at GamesOnWhales.WolfApi.GetAppsAsync()
         at WolfLeash.Components.Pages.Apps.Show.OnInitializedAsync() in /src/WolfLeash/Components/Pages/Apps/Show.razor:line 48
         at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

Switched over the container and am getting this crash as soon as I click on Apps.

<!-- gh-comment-id:4586989556 --> @Hukuma1 commented on GitHub (May 31, 2026): ``` info: Microsoft.Hosting.Lifetime[14] Now listening on: http://[::]:8080 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production info: Microsoft.Hosting.Lifetime[0] Content root path: /app fail: Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery[7] An exception was thrown while deserializing the token. Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {dec2da64-a204-4e83-ade3-c5481523483f} was not found in the key ring. For more information go to https://aka.ms/aspnet/dataprotectionwarning at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) --- End of inner exception stack trace --- at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext) warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100] Unhandled exception rendering component: Could not deserialize the response body stream as GamesOnWhales.AppListResponse. Status: 200 Response: HTTP Response: GamesOnWhales.ApiException: Could not deserialize the response body stream as GamesOnWhales.AppListResponse. Status: 200 Response: ---> Newtonsoft.Json.JsonSerializationException: Required property 'name' not found in JSON. Path 'apps[1].runner', line 1, position 7005. at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EndProcessProperty(Object newObject, JsonReader reader, JsonObjectContract contract, Int32 initialDepth, JsonProperty property, PropertyPresence presence, Boolean setDefaultValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader) at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken) --- End of inner exception stack trace --- at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken) at GamesOnWhales.GeneratedApiClient.AppsAsync(CancellationToken cancellationToken) at GamesOnWhales.WolfApi.GetAppsAsync() at WolfLeash.Components.Pages.Apps.Show.OnInitializedAsync() in /src/WolfLeash/Components/Pages/Apps/Show.razor:line 48 at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState) fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111] Unhandled exception in circuit 'bVs1W2FZDyYO2w0BekiQqash0foL0nqmsGMeRe6uwCE'. HTTP Response: GamesOnWhales.ApiException: Could not deserialize the response body stream as GamesOnWhales.AppListResponse. Status: 200 Response: ---> Newtonsoft.Json.JsonSerializationException: Required property 'name' not found in JSON. Path 'apps[1].runner', line 1, position 7005. at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EndProcessProperty(Object newObject, JsonReader reader, JsonObjectContract contract, Int32 initialDepth, JsonProperty property, PropertyPresence presence, Boolean setDefaultValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader) at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken) --- End of inner exception stack trace --- at GamesOnWhales.GeneratedApiClient.ReadObjectResponseAsync[T](HttpResponseMessage response, IReadOnlyDictionary`2 headers, CancellationToken cancellationToken) at GamesOnWhales.GeneratedApiClient.AppsAsync(CancellationToken cancellationToken) at GamesOnWhales.WolfApi.GetAppsAsync() at WolfLeash.Components.Pages.Apps.Show.OnInitializedAsync() in /src/WolfLeash/Components/Pages/Apps/Show.razor:line 48 at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState) ``` Switched over the container and am getting this crash as soon as I click on Apps.
Author
Owner

@Skerga commented on GitHub (May 31, 2026):

I'll check that tomorrow, but it is a problem with the API I need to check if there was a change in the newer wolf versions, maybe my local wolf install is outdated.

<!-- gh-comment-id:4587667350 --> @Skerga commented on GitHub (May 31, 2026): I'll check that tomorrow, but it is a problem with the API I need to check if there was a change in the newer wolf versions, maybe my local wolf install is outdated.
Author
Owner

@Skerga commented on GitHub (Jun 3, 2026):

Could it be that you have the Test ball App in your moonlight-profile-id Profile? If that's the case then I've might have found the cause of the bug. Since Testball is a Process runner it's structured a bit different and that might trip the API Client since normally there is no non Docker runner in use anymore, except the Testball app to test the connection.
I'll have to fix that in the API and I remember that the client code generator made problems with enabling multiple runner types as return types of the same request.

TLDR: It might take me some while to fix the root cause of this, I can either remove the App list for moonlight-profile-id apps for the time being, or the users need to make sure that there is no Testball app or any other Process runner in their config.

<!-- gh-comment-id:4613678837 --> @Skerga commented on GitHub (Jun 3, 2026): Could it be that you have the Test ball App in your `moonlight-profile-id` Profile? If that's the case then I've might have found the cause of the bug. Since Testball is a Process runner it's structured a bit different and that might trip the API Client since normally there is no non Docker runner in use anymore, except the Testball app to test the connection. I'll have to fix that in the API and I remember that the client code generator made problems with enabling multiple runner types as return types of the same request. TLDR: It might take me some while to fix the root cause of this, I can either remove the App list for `moonlight-profile-id` apps for the time being, or the users need to make sure that there is no Testball app or any other Process runner in their config.
Author
Owner

@Hukuma1 commented on GitHub (Jun 3, 2026):

[[profiles]]
icon_png_path = ''
id = 'moonlight-profile-id'
name = ''

    [[profiles.apps]]
    icon_png_path = '/etc/wolf/covers/mycustomicon.png'
    render_node = '/dev/dri/renderD128'
    start_audio_server = true
    start_virtual_compositor = true
    title = 'My Custom Name'

        [profiles.apps.runner]
        base_create_json = '''{
      "HostConfig": {
        "IpcMode": "host",
        "CapAdd": ["NET_RAW", "MKNOD", "NET_ADMIN", "SYS_ADMIN", "SYS_NICE"],
        "Privileged": false,
        "DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"]
      }
    }'''
        devices = []
        env = [
            'GOW_REQUIRED_DEVICES=/dev/input/event* /dev/dri/* /dev/nvidia*',
            'WOLF_SOCKET_PATH=/var/run/wolf/wolf.sock',
            'WOLF_UI_AUTOUPDATE=False',
            'LOGLEVEL=INFO'
        ]
        image = 'ghcr.io/games-on-whales/wolf-ui:main'
        mounts = [ '/var/run/wolf/wolf.sock:/var/run/wolf/wolf.sock:rw' ]
        name = 'Wolf-UI'
        ports = []
        type = 'docker'

    [[profiles.apps]]
    icon_png_path = 'https://raw.githubusercontent.com/games-on-whales/wolf/refs/heads/stable/docs/images/test_ball_icon.png'
    render_node = '/dev/dri/renderD128'
    start_audio_server = false
    start_virtual_compositor = false
    title = 'Test ball'

        [profiles.apps.runner]
        run_cmd = "sh -c \"while :; do echo 'running...'; sleep 10; done\""
        type = 'process'

Should I just remove Test Ball and it should work? I can give it a shot!

<!-- gh-comment-id:4613752761 --> @Hukuma1 commented on GitHub (Jun 3, 2026): ``` [[profiles]] icon_png_path = '' id = 'moonlight-profile-id' name = '' [[profiles.apps]] icon_png_path = '/etc/wolf/covers/mycustomicon.png' render_node = '/dev/dri/renderD128' start_audio_server = true start_virtual_compositor = true title = 'My Custom Name' [profiles.apps.runner] base_create_json = '''{ "HostConfig": { "IpcMode": "host", "CapAdd": ["NET_RAW", "MKNOD", "NET_ADMIN", "SYS_ADMIN", "SYS_NICE"], "Privileged": false, "DeviceCgroupRules": ["c 13:* rmw", "c 244:* rmw"] } }''' devices = [] env = [ 'GOW_REQUIRED_DEVICES=/dev/input/event* /dev/dri/* /dev/nvidia*', 'WOLF_SOCKET_PATH=/var/run/wolf/wolf.sock', 'WOLF_UI_AUTOUPDATE=False', 'LOGLEVEL=INFO' ] image = 'ghcr.io/games-on-whales/wolf-ui:main' mounts = [ '/var/run/wolf/wolf.sock:/var/run/wolf/wolf.sock:rw' ] name = 'Wolf-UI' ports = [] type = 'docker' [[profiles.apps]] icon_png_path = 'https://raw.githubusercontent.com/games-on-whales/wolf/refs/heads/stable/docs/images/test_ball_icon.png' render_node = '/dev/dri/renderD128' start_audio_server = false start_virtual_compositor = false title = 'Test ball' [profiles.apps.runner] run_cmd = "sh -c \"while :; do echo 'running...'; sleep 10; done\"" type = 'process' ``` Should I just remove Test Ball and it should work? I can give it a shot!
Author
Owner

@Skerga commented on GitHub (Jun 3, 2026):

Yeah but I'm also about to push a change to disable the Moonlight apps showing up in the Apps list. that should also fix the issue for the time until it can be properly fixed in the API code.
If you prefer to keep the Testball app for testing purposes then just wait for the push.

<!-- gh-comment-id:4613792422 --> @Skerga commented on GitHub (Jun 3, 2026): Yeah but I'm also about to push a change to disable the Moonlight apps showing up in the Apps list. that should also fix the issue for the time until it can be properly fixed in the API code. If you prefer to keep the Testball app for testing purposes then just wait for the push.
Author
Owner

@Hukuma1 commented on GitHub (Jun 3, 2026):

So I pulled the new dev container and it now populates the list just fine without crashing. Awesome!

But I am unable to add any default apps that were deleted? Or am I missing some menu? Is there a way to restore the default apps that were removed?

<!-- gh-comment-id:4614938631 --> @Hukuma1 commented on GitHub (Jun 3, 2026): So I pulled the new dev container and it now populates the list just fine without crashing. Awesome! But I am unable to add any default apps that were deleted? Or am I missing some menu? Is there a way to restore the default apps that were removed?
Author
Owner

@Skerga commented on GitHub (Jun 3, 2026):

Just add a new Profile, the option is in there, for the moment. I'll also add a drop down for default app templates when adding a new apps in the future.

<!-- gh-comment-id:4614962411 --> @Skerga commented on GitHub (Jun 3, 2026): Just add a new Profile, the option is in there, for the moment. I'll also add a drop down for default app templates when adding a new apps in the future.
Author
Owner

@Skerga commented on GitHub (Jun 3, 2026):

Just pushed a commit that should allow you to choose a Template from Wildlife (Default Apps) when adding a new App/ editing an old one.

<!-- gh-comment-id:4615339071 --> @Skerga commented on GitHub (Jun 3, 2026): Just pushed a commit that should allow you to choose a Template from Wildlife (Default Apps) when adding a new App/ editing an old one.
Author
Owner

@Hukuma1 commented on GitHub (Jun 3, 2026):

Just tested it. Works great, thank you!

<!-- gh-comment-id:4615798696 --> @Hukuma1 commented on GitHub (Jun 3, 2026): Just tested it. Works great, thank you!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/wolf-den#12
No description provided.