I am making a graphics renderer in Vulkan using C++. I am currently running into an error that I'm hoping you can help with. While changing some of the code to allow for more flexible descriptor set creation, I've started getting an error seemlingly related to a mismatch between buffer usage and descriptor type, but I fail to see what might be causing it. Here is the error:

VUID-VkWriteDescriptorSet-descriptorType-00331(ERROR / SPEC): msgNum: -561209641 - Validation Error: [ VUID-VkWriteDescriptorSet-descriptorType-00331 ] Object 0: handle = 0x612f93000000004e, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0xde8c9ed7 | vkUpdateDescriptorSets() pDescriptorWrites[0] failed write update validation for VkDescriptorSet 0x612f93000000004e[] with error: Write update to VkDescriptorSet 0x612f93000000004e[] allocated with VkDescriptorSetLayout 0x5c5283000000003e[] binding #0 failed with error message: Attempted write update to buffer descriptor failed due to: Buffer (VkBuffer 0x4f8a8b0000000046[]) with usage mask 0x10 being used for a descriptor update of type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER does not have VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set.. The Vulkan spec states: If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the buffer member of each element of pBufferInfo must have been created with VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set (https://vulkan.lunarg.com/doc/view/1.3.239.0/windows/1.3-extensions/vkspec.html#VUID-VkWriteDescriptorSet-descriptorType-00331)
    Objects: 1
        [0] 0x612f93000000004e, type: 23, name: NULL

Here are the relevant sections of code:

Parts of the main setup function:

modelMatrixBufferobj = BufferUtils::CreateBuffer2(*renderer.GetDevice(), *renderer.GetPhysicalDevice(), sizeof(glm::mat4) * modelcount,
		vk::BufferUsageFlagBits::eStorageBuffer,
		vk::MemoryPropertyFlagBits::
		eHostVisible | vk::
		MemoryPropertyFlagBits ::
		eHostCoherent);

	viewMatrixBufferobj = BufferUtils::CreateBuffer2(*renderer.GetDevice(), *renderer.GetPhysicalDevice(), sizeof(glm::mat4),
		vk::BufferUsageFlagBits::eUniformBuffer,
		vk::MemoryPropertyFlagBits::
		eHostVisible | vk::
		MemoryPropertyFlagBits ::
		eHostCoherent);

	projMatrixBufferobj = BufferUtils::CreateBuffer2(*renderer.GetDevice(), *renderer.GetPhysicalDevice(), sizeof(glm::mat4),
		vk::BufferUsageFlagBits::eUniformBuffer,
		vk::MemoryPropertyFlagBits::
		eHostVisible | vk::
		MemoryPropertyFlagBits ::
		eHostCoherent);

	modelCountBufferobj = BufferUtils::CreateBuffer2(*renderer.GetDevice(), *renderer.GetPhysicalDevice(), sizeof(int),
		vk::BufferUsageFlagBits::eUniformBuffer,
		vk::MemoryPropertyFlagBits::
		eHostVisible | vk::
		MemoryPropertyFlagBits ::
		eHostCoherent);

	ambientLightBufferobj = BufferUtils::CreateBuffer2(*renderer.GetDevice(), *renderer.GetPhysicalDevice(), sizeof(AmbientLight),
		vk::BufferUsageFlagBits::eUniformBuffer,
		vk::MemoryPropertyFlagBits::
		eHostVisible | vk::
		MemoryPropertyFlagBits ::
		eHostCoherent);

	directionalLightBufferobj = BufferUtils::CreateBuffer2(*renderer.GetDevice(), *renderer.GetPhysicalDevice(), sizeof(DirectionalLight),
		vk::BufferUsageFlagBits::eUniformBuffer,
		vk::MemoryPropertyFlagBits::
		eHostVisible | vk::
		MemoryPropertyFlagBits ::
		eHostCoherent);

std::vector<std::vector<std::variant<BufferUtils::BufferObject*, vk::DescriptorType, vk::ImageLayout, vk::ImageView, vk::Sampler, int>>> geomdescriptorinput =
	{
	{0,&modelMatrixBufferobj,vk::DescriptorType::eStorageBuffer},
	{0,&viewMatrixBufferobj,vk::DescriptorType::eUniformBuffer},
	{0,&projMatrixBufferobj,vk::DescriptorType::eUniformBuffer},
	{1,vk::ImageLayout::eShaderReadOnlyOptimal,textures[1].get()->GetImageView(),textures[1].get()->GetSampler(),vk::DescriptorType::eCombinedImageSampler}
	};

CreateGeomDescriptorSet2(*renderer.GetDevice(), geomdescriptorinput, descriptorPool, geomdescriptorSetLayout);

Other related functions:

 BufferObject CreateBuffer2(
        vk::Device device, vk::PhysicalDevice physicalDevice,
        vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties)
    {
        BufferObject bufferobj;
        bufferobj.size = size;
        bufferobj.usage = usage;
        bufferobj.device = &device;

        vk::BufferCreateInfo bufferInfo;
        bufferInfo.size = size;
        bufferInfo.usage = usage;
        bufferInfo.sharingMode = vk::SharingMode::eExclusive;

        bufferobj.buffer = device.createBuffer(bufferInfo);

        vk::MemoryRequirements memRequirements = device.getBufferMemoryRequirements(bufferobj.buffer);

        vk::MemoryAllocateInfo allocInfo;
        allocInfo.allocationSize = memRequirements.size;
        allocInfo.memoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.memoryTypeBits, properties);

        bufferobj.memory = device.allocateMemory(allocInfo);

        device.bindBufferMemory(bufferobj.buffer, bufferobj.memory, 0);
        return bufferobj;
    }

void Engine::CreateGeomDescriptorSet2(vk::Device device, std::vector<std::vector<std::variant<BufferUtils::BufferObject*, vk::DescriptorType, vk::ImageLayout, vk::ImageView, vk::Sampler, int>>> descriptorinput, vk::UniqueDescriptorPool& descriptorPool, vk::DescriptorSetLayout descriptorSetLayout) {
	vk::DescriptorSetAllocateInfo allocInfo{};
	allocInfo.setDescriptorPool(descriptorPool.get());
	allocInfo.setDescriptorSetCount(1);
	allocInfo.setPSetLayouts(&descriptorSetLayout);

	geomdescriptorSet = std::move(device.allocateDescriptorSetsUnique(allocInfo)[0]);

	if (!geomdescriptorSet) {
		throw std::runtime_error("Failed to allocate descriptor set!");
	}


	std::vector<vk::WriteDescriptorSet> descriptorWrites{};

	for (int i = 0; i < descriptorinput.size(); i++) {

		if (std::get<int>(descriptorinput[i][0]) == 0) {
			vk::DescriptorBufferInfo bufferInfo{};
			bufferInfo.buffer = std::get<BufferUtils::BufferObject*>(descriptorinput[i][1])->buffer;
			bufferInfo.offset = 0;
			bufferInfo.range = std::get<BufferUtils::BufferObject*>(descriptorinput[i][1])->size;

			vk::WriteDescriptorSet descriptorWrite;
			descriptorWrite.setDstSet(geomdescriptorSet.get());
			descriptorWrite.setDstBinding(i);
			descriptorWrite.setDstArrayElement(0);
			descriptorWrite.setDescriptorType(std::get<vk::DescriptorType>(descriptorinput[i][2]));
			descriptorWrite.setDescriptorCount(1);
			descriptorWrite.setPBufferInfo(&bufferInfo);

			descriptorWrites.push_back(descriptorWrite);
		}
		else if (std::get<int>(descriptorinput[i][0]) == 1) {
			vk::DescriptorImageInfo imageInfo{};
			imageInfo.imageLayout = std::get<vk::ImageLayout>(descriptorinput[i][1]);
			imageInfo.imageView = std::get<vk::ImageView>(descriptorinput[i][2]);
			imageInfo.sampler = std::get<vk::Sampler>(descriptorinput[i][3]);

			vk::WriteDescriptorSet descriptorWrite;
			descriptorWrite.setDstSet(geomdescriptorSet.get());
			descriptorWrite.setDstBinding(i);
			descriptorWrite.setDstArrayElement(0);
			descriptorWrite.setDescriptorType(std::get<vk::DescriptorType>(descriptorinput[i][4]));
			descriptorWrite.setDescriptorCount(1);
			descriptorWrite.setPImageInfo(&imageInfo);

			descriptorWrites.push_back(descriptorWrite);
		}
	}

	device.updateDescriptorSets(static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
}