diff --git a/include/libcamera/internal/value_node.h b/include/libcamera/internal/value_node.h
index dd45859f3501..56d200e1cf27 100644
--- a/include/libcamera/internal/value_node.h
+++ b/include/libcamera/internal/value_node.h
@@ -143,17 +143,31 @@ public:
 		}
 	};
 
-	class DictAdapter : public Adapter<DictIterator<const ValueNode,
-							ValueContainer::const_iterator>,
-					   const ValueContainer>
+	class DictAdapter : public Adapter<DictIterator<ValueNode,
+							ValueContainer::iterator>,
+					   ValueContainer>
 	{
 	public:
 		using key_type = std::string;
 	};
 
-	class ListAdapter : public Adapter<ListIterator<const ValueNode,
-							ValueContainer::const_iterator>,
-					   const ValueContainer>
+	class ListAdapter : public Adapter<ListIterator<ValueNode,
+							ValueContainer::iterator>,
+					   ValueContainer>
+	{
+	};
+
+	class ConstDictAdapter : public Adapter<DictIterator<const ValueNode,
+							     ValueContainer::const_iterator>,
+						const ValueContainer>
+	{
+	public:
+		using key_type = std::string;
+	};
+
+	class ConstListAdapter : public Adapter<ListIterator<const ValueNode,
+							     ValueContainer::const_iterator>,
+						const ValueContainer>
 	{
 	};
 #endif /* __DOXYGEN__ */
@@ -209,8 +223,10 @@ public:
 		return Accessor<std::remove_reference_t<T>>{}.set(*this, std::forward<T>(value));
 	}
 
-	DictAdapter asDict() const { return DictAdapter{ list_ }; }
-	ListAdapter asList() const { return ListAdapter{ list_ }; }
+	DictAdapter asDict() { return DictAdapter{ list_ }; }
+	ListAdapter asList() { return ListAdapter{ list_ }; }
+	ConstDictAdapter asDict() const { return ConstDictAdapter{ list_ }; }
+	ConstListAdapter asList() const { return ConstListAdapter{ list_ }; }
 
 	const ValueNode &operator[](std::size_t index) const;
 
diff --git a/src/libcamera/value_node.cpp b/src/libcamera/value_node.cpp
index b8f0c6d5cbc4..3c56b47bf79d 100644
--- a/src/libcamera/value_node.cpp
+++ b/src/libcamera/value_node.cpp
@@ -335,6 +335,11 @@ template struct ValueNode::Accessor<std::vector<uint32_t>>;
 template struct ValueNode::Accessor<std::vector<std::string>>;
 #endif /* __DOXYGEN__ */
 
+/**
+ * \fn ValueNode::asDict()
+ * \copydoc ValueNode::asDict() const
+ */
+
 /**
  * \fn ValueNode::asDict() const
  * \brief Wrap a dictionary ValueNode in an adapter that exposes iterators
@@ -355,6 +360,11 @@ template struct ValueNode::Accessor<std::vector<std::string>>;
  * \return An adapter of unspecified type compatible with range-based for loops
  */
 
+/**
+ * \fn ValueNode::asList()
+ * \copydoc ValueNode::asList() const
+ */
+
 /**
  * \fn ValueNode::asList() const
  * \brief Wrap a list ValueNode in an adapter that exposes iterators
