Skip to content

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

Description

@plazmer

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ⚙️ In-progressIssues, Features requests that are in Progress🐞 BugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions