I am having problems with cleaning up VkDescriptorSet and VkDescriptorPool

private:
    GLFWwindow* window;

    VkInstance instance;
    VkDebugUtilsMessengerEXT debugMessenger;
    VkSurfaceKHR surface;

    VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
    VkDevice device;

    VkQueue graphicsQueue;
    VkQueue presentQueue;

    VkSwapchainKHR swapChain;
    std::vector<VkImage> swapChainImages;
    VkFormat swapChainImageFormat;
    VkExtent2D swapChainExtent;
    std::vector<VkImageView> swapChainImageViews;
    std::vector<VkFramebuffer> swapChainFramebuffers;

    VkRenderPass renderPass;
    VkDescriptorSetLayout descriptorSetLayout;
    VkPipelineLayout pipelineLayout;
    VkPipeline graphicsPipeline;

    VkCommandPool commandPool;

    VkImage textureImage;
    VkDeviceMemory textureImageMemory;
    VkImageView textureImageView;
    VkSampler textureSampler;

    VkBuffer vertexBuffer;
    VkDeviceMemory vertexBufferMemory;
    VkBuffer indexBuffer;
    VkDeviceMemory indexBufferMemory;

    std::vector<VkBuffer> uniformBuffers;
    std::vector<VkDeviceMemory> uniformBuffersMemory;
    std::vector<void*> uniformBuffersMapped;

    VkDescriptorPool descriptorPool; // just one pool
    std::vector<std::vector<VkDescriptorSet>> descriptorSets; // [texture][frame]

    std::vector<VkCommandBuffer> commandBuffers;

    std::vector<VkSemaphore> imageAvailableSemaphores;
    std::vector<VkSemaphore> renderFinishedSemaphores;
    std::vector<VkFence> inFlightFences;
    uint32_t currentFrame = 0;

    bool framebufferResized = false;

    std::vector<VkImage> textureImages;
    std::vector<VkImageView> textureImageViews;
    std::vector<VkSampler> textureSamplers;
    std::vector<VkDeviceMemory> textureImageMemories;

    const uint32_t textureCount = 2;
    
    void initVulkan(char* argv) {
        createInstance();
        setupDebugMessenger();
        createSurface();
        pickPhysicalDevice();
        createLogicalDevice();
        createSwapChain();
        createImageViews();
        createRenderPass();
        createDescriptorSetLayout();
        createGraphicsPipeline();
        createFramebuffers();
        createCommandPool();

        textureImages.resize(textureCount);
        textureImageMemories.resize(textureCount);
        textureImageViews.resize(textureCount);
        textureSamplers.resize(textureCount);
        descriptorSets.resize(textureCount);

        createIndexBuffer();
        createUniformBuffers();
        createVertexBuffer();
        createDescriptorPool(0); // ONE pool for all textures

        // --- Create all textures and descriptor sets ---
        createTextureImage("images/png/Transparency.png", 0);
        createTextureImageView(0);
        createTextureSampler(0);
        createDescriptorSets(0, descriptorSets[0]);

        createDescriptorPool(1); // ONE pool for all textures
        createTextureImage("images/png/penguin_transparent.png", 1);
        createTextureImageView(1);
        createTextureSampler(1);
        createDescriptorSets(1, descriptorSets[1]);

        createCommandBuffers();
        createSyncObjects();
    }

        void cleanup() {
        cleanupSwapChain();

        // Group all pipeline-related objects together
        vkDestroyPipeline(device, graphicsPipeline, nullptr);
        vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
        vkDestroyRenderPass(device, renderPass, nullptr);

        // Destroy resources like buffers and images
        for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
            vkDestroyBuffer(device, uniformBuffers[i], nullptr);
            vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
        }
    

        // Iterate through the outer vector
        for (auto& inner_vector : descriptorSets) {
            // Free the inner vector's descriptor sets
            if (!inner_vector.empty()) {
                vkFreeDescriptorSets(device, descriptorPool, static_cast<uint32_t>(inner_vector.size()), inner_vector.data());
            }
        }

        vkDestroyDescriptorPool(device, descriptorPool, nullptr); // This also frees the descriptor sets
        vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); // Moved up
        descriptorSets.clear();

        for (size_t i = 0; i < textureImages.size(); i++) {
            vkDestroySampler(device, textureSamplers[i], nullptr);
            vkDestroyImageView(device, textureImageViews[i], nullptr);
            vkDestroyImage(device, textureImages[i], nullptr);
            vkFreeMemory(device, textureImageMemories[i], nullptr);
        }
        
        vkDestroyBuffer(device, indexBuffer, nullptr);
        vkFreeMemory(device, indexBufferMemory, nullptr);

        vkDestroyBuffer(device, vertexBuffer, nullptr);
        vkFreeMemory(device, vertexBufferMemory, nullptr);

        // Destroy synchronization and command objects
        for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
            vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
            vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
            vkDestroyFence(device, inFlightFences[i], nullptr);
        }

        vkDestroyCommandPool(device, commandPool, nullptr);

        // Destroy the core Vulkan objects
        vkDestroyDevice(device, nullptr);

        if (enableValidationLayers) {
            DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
        }

        vkDestroySurfaceKHR(instance, surface, nullptr);
        vkDestroyInstance(instance, nullptr);

        // Terminate the windowing system
        glfwDestroyWindow(window);
        glfwTerminate();
    }
i get this error
    validation layer: Validation Error: [ VUID-vkDestroyDevice-device-05137 ] Object 0: handle = 0x3fbcd60000000028, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0x4872eaa0 | vkCreateDevice():  OBJ ERROR : For VkDevice 0x12883fa18[], VkDescriptorSet 0x3fbcd60000000028[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.3.275.0/mac/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-05137)
validation layer: Validation Error: [ VUID-vkDestroyDevice-device-05137 ] Object 0: handle = 0xb097c90000000027, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0x4872eaa0 | vkCreateDevice():  OBJ ERROR : For VkDevice 0x12883fa18[], VkDescriptorSet 0xb097c90000000027[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.3.275.0/mac/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-05137)
validation layer: Validation Error: [ VUID-vkDestroyDevice-device-05137 ] Object 0: handle = 0xab64de0000000020, type = VK_OBJECT_TYPE_DESCRIPTOR_POOL; | MessageID = 0x4872eaa0 | vkCreateDevice():  OBJ ERROR : For VkDevice 0x12883fa18[], VkDescriptorPool 0xab64de0000000020[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.3.275.0/mac/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-05137)
validation layer: Unloading layer library /usr/local/share/vulkan/explicit_layer.d/../../../lib/libVkLayer_khronos_validation.dylib

can someone please help?
I am using vulkan 1.3.275.0

I don’t know what exactly createDescriptorPool does, but if the function does what it says, you are clearly creating two descriptor pools. And then two descriptor sets.

Thanks. Just made a container for DescriptorPool and deleted what’s inside it thank.

Coding is swimmingly fun.
Not there what you are thinking.