{"record":{"id":"567d78de5f9bbb6e","repo":"langchain-ai/langchain","slug":"remapping-for-fields-starting-with-or-fields-w","errorCode":null,"errorMessage":"Remapping for fields starting with '_' or fields with a name matching a reserved name {_RESERVED_NAMES} is not supported if  the field is a pydantic Field instance. Got {key}.","messagePattern":"Remapping for fields starting with '_' or fields with a name matching a reserved name (.+?) is not supported if  the field is a pydantic Field instance\\. Got (.+?)\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/utils/pydantic.py","lineNumber":540,"sourceCode":"# \"model_fields_set\", \"model_json_schema\", \"model_parametrized_name\",\n# \"model_post_init\", \"model_rebuild\", \"model_validate\", \"model_validate_json\",\n# \"model_validate_strings\"\n_RESERVED_NAMES = {key for key in dir(BaseModel) if not key.startswith(\"_\")}\n\n\ndef _remap_field_definitions(field_definitions: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"This remaps fields to avoid colliding with internal pydantic fields.\"\"\"\n    remapped = {}\n    for key, value in field_definitions.items():\n        if key.startswith(\"_\") or key in _RESERVED_NAMES:\n            # Let's add a prefix to avoid colliding with internal pydantic fields\n            if isinstance(value, FieldInfoV2):\n                msg = (\n                    f\"Remapping for fields starting with '_' or fields with a name \"\n                    f\"matching a reserved name {_RESERVED_NAMES} is not supported if \"\n                    f\" the field is a pydantic Field instance. Got {key}.\"\n                )\n                raise NotImplementedError(msg)\n            type_, default_ = value\n            remapped[f\"private_{key}\"] = (\n                type_,\n                Field(\n                    default=default_,\n                    alias=key,\n                    serialization_alias=key,\n                    title=key.lstrip(\"_\").replace(\"_\", \" \").title(),\n                ),\n            )\n        else:\n            remapped[key] = value\n    return remapped\n\n\ndef create_model_v2(\n    model_name: str,\n    *,","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/utils/pydantic.py#L522-L558","documentation":"Raised by `_remap_field_definitions` in `langchain_core.utils.pydantic` (used by `create_model`-style dynamic model creation) when a field name starts with `_` or collides with a pydantic-reserved name (`model_`-prefixed / internal names in `_RESERVED_NAMES`) AND the field value is a pydantic `FieldInfo` (i.e. `Field(...)`). Remapping such names relies on re-wrapping a `(type, default)` tuple; it cannot preserve a full `FieldInfo`, so it refuses with `NotImplementedError` instead of silently dropping constraints.","triggerScenarios":"Building a dynamic model (e.g. via `langchain_core.utils.pydantic.create_model` / tool-args model creation) with field definitions like `{\"_private\": (str, Field(...))}` or `{\"model_config_override\": Field(default=1, ...)}` — any reserved/underscore name mapped to a `Field(...)` instance rather than a `(type, default)` tuple.","commonSituations":"Structured-output schemas generated from external specs (OpenAPI, JSON Schema, database columns) that contain leading-underscore or `model_*` column names; converting user-supplied dicts into tool argument models where keys are arbitrary; naming a field `model_fields`, `model_config`, etc.","solutions":["Rename the field so it does not start with `_` and is not in `_RESERVED_NAMES` (preferred — remapping then works and keeps an alias).","If renaming is impossible, define the field as a plain tuple `(type, default)` instead of `Field(...)`; the helper can then remap it with an alias preserving the original name.","Pre-normalize external field names (strip leading underscores, prefix reserved names) before generating the model."],"exampleFix":"# before\ncreate_model(\"M\", **{\"_count\": (int, Field(default=0, ge=0))})  # NotImplementedError\n\n# after\ncreate_model(\"M\", **{\"_count\": (int, 0)})  # tuple form: remapped with alias '_count'\n# or better: rename\ncreate_model(\"M\", count=(int, Field(default=0, ge=0)))","handlingStrategy":"validation","validationCode":"from langchain_core.utils.pydantic import _RESERVED_NAMES\nfrom pydantic.fields import FieldInfo\n\ndef check_field_defs(field_definitions: dict) -> None:\n    for name, value in field_definitions.items():\n        if (name.startswith(\"_\") or name in _RESERVED_NAMES) and isinstance(value, FieldInfo):\n            raise ValueError(\n                f\"field {name!r}: reserved/underscore names must use (type, default) tuples, not Field(...)\"\n            )","typeGuard":null,"tryCatchPattern":"try:\n    create_model(\"M\", **field_definitions)\nexcept NotImplementedError as e:\n    # rewrite offending FieldInfo as (type, default) and retry\n    ...","preventionTips":["Sanitize external field names (strip leading '_', rename model_* keys) before create_model.","Reserve Field(...) for non-underscore, non-reserved names only.","Add a unit test for dynamic model generation from your spec source."],"tags":["pydantic","dynamic-model","field-names","reserved-names"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}