diff --git a/dask/core.py b/dask/core.py
index 59d9fd921..153c39a4d 100644
--- a/dask/core.py
+++ b/dask/core.py
@@ -463,6 +463,6 @@ def quote(x):
     >>> quote((add, 1, 2))  # doctest: +SKIP
     (literal<type=tuple>,)
     """
-    if istask(x) or type(x) is list:
+    if istask(x) or type(x) is list or type(x) is dict:
         return (literal(x),)
     return x

dask.core.quote does not quote dicts
It seems that dask now recurses into dicts stored within a graph to find keys (I'm not quite sure when that came in: #1748 proposed it but was never merged). However, `quote` doesn't take that into account.

```python3
from dask import core
core.get({"x": quote({"a": "x"})}, "x")
```

Produces
```
RuntimeError: Cycle detected in Dask: x->x
```

I'll make a PR to fix it.
diff --git a/dask/tests/test_core.py b/dask/tests/test_core.py
index 8ebe0acd3..1f8eacb88 100644
--- a/dask/tests/test_core.py
+++ b/dask/tests/test_core.py
@@ -250,7 +250,7 @@ def test_subs_unexpected_hashable_key():
 
 
 def test_quote():
-    literals = [[1, 2, 3], (add, 1, 2), [1, [2, 3]], (add, 1, (add, 2, 3))]
+    literals = [[1, 2, 3], (add, 1, 2), [1, [2, 3]], (add, 1, (add, 2, 3)), {"x": "x"}]
 
     for l in literals:
         assert core.get({"x": quote(l)}, "x") == l

pip install -e .[complete]
parse_log_pytest
pytest
pytest
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
bokeh==3.4.3
click==8.1.8
cloudpickle==3.1.1
contourpy==1.3.0
-e git+https://github.com/dask/dask.git@5a7f4524217d0d3ee9e44b6b6513264de7f16171#egg=dask
distributed==2.30.1
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
fsspec==2025.3.1
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
Jinja2==3.1.6
locket==1.0.0
MarkupSafe==3.0.2
msgpack==1.1.0
numpy==2.0.2
packaging @ file:///croot/packaging_1734472117206/work
pandas==2.2.3
partd==1.4.2
pillow==11.1.0
pluggy @ file:///croot/pluggy_1733169602837/work
psutil==7.0.0
pytest @ file:///croot/pytest_1738938843180/work
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.2
six==1.17.0
sortedcontainers==2.4.0
tblib==3.1.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
toolz==1.0.0
tornado==6.4.2
tzdata==2025.2
xyzservices==2025.1.0
zict==3.0.0

name: dask
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - bokeh==3.4.3
      - click==8.1.8
      - cloudpickle==3.1.1
      - contourpy==1.3.0
      - distributed==2.30.1
      - fsspec==2025.3.1
      - jinja2==3.1.6
      - locket==1.0.0
      - markupsafe==3.0.2
      - msgpack==1.1.0
      - numpy==2.0.2
      - pandas==2.2.3
      - partd==1.4.2
      - pillow==11.1.0
      - psutil==7.0.0
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyyaml==6.0.2
      - six==1.17.0
      - sortedcontainers==2.4.0
      - tblib==3.1.0
      - toolz==1.0.0
      - tornado==6.4.2
      - tzdata==2025.2
      - xyzservices==2025.1.0
      - zict==3.0.0
prefix: /opt/conda/envs/dask

dask/tests/test_core.py::test_quote
dask/tests/test_core.py::test_istask dask/tests/test_core.py::test_has_tasks dask/tests/test_core.py::test_preorder_traversal dask/tests/test_core.py::TestGet::test_get dask/tests/test_core.py::TestGet::test_badkey dask/tests/test_core.py::TestGet::test_nested_badkey dask/tests/test_core.py::TestGet::test_data_not_in_dict_is_ok dask/tests/test_core.py::TestGet::test_get_with_list dask/tests/test_core.py::TestGet::test_get_with_list_top_level dask/tests/test_core.py::TestGet::test_get_with_nested_list dask/tests/test_core.py::TestGet::test_get_works_with_unhashables_in_values dask/tests/test_core.py::TestGet::test_nested_tasks dask/tests/test_core.py::TestGet::test_get_stack_limit dask/tests/test_core.py::TestGet::test_with_HighLevelGraph dask/tests/test_core.py::test_GetFunctionTestMixin_class dask/tests/test_core.py::test_get_dependencies_nested dask/tests/test_core.py::test_get_dependencies_empty dask/tests/test_core.py::test_get_dependencies_list dask/tests/test_core.py::test_get_dependencies_task dask/tests/test_core.py::test_get_dependencies_nothing dask/tests/test_core.py::test_get_dependencies_many dask/tests/test_core.py::test_get_dependencies_task_none dask/tests/test_core.py::test_get_deps dask/tests/test_core.py::test_flatten dask/tests/test_core.py::test_subs dask/tests/test_core.py::test_subs_no_key_data_eq dask/tests/test_core.py::test_subs_with_unfriendly_eq dask/tests/test_core.py::test_subs_with_surprisingly_friendly_eq dask/tests/test_core.py::test_subs_unexpected_hashable_key dask/tests/test_core.py::test_literal_serializable
dask/core.py
dask/core.py