[Bug]: Playground: /md and /llm endpoints always fail because Advanced Config `code` is sent to /config/dump

Open Beginner friendly
#2,222 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
86/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
docker, javascript, python
Domain
api, frontend

Research direction

Start in deploy/docker/static/playground/index.html, focusing on runCrawl() and pyConfigToJson(). Reproduce the failure with the Docker server using the default Advanced Config and the md endpoint, then verify that md and llm can run without the rejected /config/dump request and POST their expected inputs to the selected endpoint.

Written by the indexing model from the issue text.

Description

⚙️ In-progress 🐞 Bug
crawl4ai version

v0.9.3

Expected Behavior

The Playground (/playground/) should work for all endpoint modes. The Advanced Config editor is a /crawl-only feature (the panel is hidden for md/llm), so selecting the md endpoint and clicking Run should simply POST { url, f, q, c } to /md — the server builds its own CrawlerRunConfig internally (handle_markdown_request). No client-side config validation should be involved.

Current Behavior

runCrawl() in deploy/docker/static/playground/index.html calls pyConfigToJson() unconditionally for every endpoint, including md and llm. pyConfigToJson() reads the Advanced Config CodeMirror editor (which defaults to the Python snippet CrawlerRunConfig(stream=True, cache_mode=CacheMode.BYPASS,)) and POSTs it to /config/dump using the removed legacy code protocol:

{ "type": "CrawlerRunConfig", "code": "CrawlerRunConfig(\n    stream=True,\n    cache_mode=CacheMode.BYPASS,\n)" }

Since the security hardening (eval removal from /config/dump + untrusted trust boundary), the server parses request bodies with Provenance.UNTRUSTED and code is a globally forbidden field, so the request is rejected with:

{ "detail": "field 'code' is not permitted on CrawlerRunConfig from an untrusted request" }

In runCrawl() the 400 error triggers the catch branch. The fallback (minimal { crawler_config: { type: 'CrawlerRunConfig', params: { stream: true } } }) only applies when endpoint === 'crawl' and the editor text contains stream=True. For md/llm the code path aborts the whole run, so the md mode is unusable even without touching the Advanced Config. The only workaround today is pasting empty text / relying on nothing, but since the editor has a non-empty default template, pyConfigToJson() always runs.

Is this reproducible?

Yes

Inputs Causing the Bug
- URL(s): https://example.com
- Endpoint: md (and llm)
- Advanced Config: default
Steps to Reproduce
1. Start the Docker server and open http://localhost:11235/playground/
2. Leave the endpoint set to "md" (default), enter any URL, leave Advanced Config untouched
3. Click "Run"
4. Observe: status flips to "error", response shows
`{ "error": "field 'code' is not permitted on CrawlerRunConfig from an untrusted request" }`
and the /md request is never sent
Code snippets

OS

Docker

Python version

3.12.14

Browser

Chrome

Browser version

No response

Error logs & Screenshots (if applicable)
Image
Dominant language
Python
Stars
83.9k
Forks
8.7k
Avg merge
3d 7h
Merged PRs (30d)
11

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from unclecode/crawl4ai

All issues in unclecode/crawl4ai

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.