{"record":{"id":"e20b5beaacd36beb","repo":"openai/openai-python","slug":"unexpected-ref-format-ref-r-does-not-start-wit","errorCode":null,"errorMessage":"Unexpected $ref format {ref!r}; Does not start with #/","messagePattern":"Unexpected \\$ref format (.+?); Does not start with #/","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/openai/lib/_pydantic.py","lineNumber":120,"sourceCode":"        assert isinstance(ref, str), f\"Received non-string $ref - {ref}\"\n\n        resolved = resolve_ref(root=root, ref=ref)\n        if not is_dict(resolved):\n            raise ValueError(f\"Expected `$ref: {ref}` to resolved to a dictionary but got {resolved}\")\n\n        # properties from the json schema take priority over the ones on the `$ref`\n        json_schema.update({**resolved, **json_schema})\n        json_schema.pop(\"$ref\")\n        # Since the schema expanded from `$ref` might not have `additionalProperties: false` applied,\n        # we call `_ensure_strict_json_schema` again to fix the inlined schema and ensure it's valid.\n        return _ensure_strict_json_schema(json_schema, path=path, root=root)\n\n    return json_schema\n\n\ndef resolve_ref(*, root: dict[str, object], ref: str) -> object:\n    if not ref.startswith(\"#/\"):\n        raise ValueError(f\"Unexpected $ref format {ref!r}; Does not start with #/\")\n\n    path = ref[2:].split(\"/\")\n    resolved = root\n    for key in path:\n        value = resolved[key]\n        assert is_dict(value), f\"encountered non-dictionary entry while resolving {ref} - {resolved}\"\n        resolved = value\n\n    return resolved\n\n\ndef is_basemodel_type(typ: type) -> TypeGuard[type[pydantic.BaseModel]]:\n    if not inspect.isclass(typ):\n        return False\n    return issubclass(typ, pydantic.BaseModel)\n\n\ndef is_dataclass_like_type(typ: type) -> bool:","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/lib/_pydantic.py#L102-L138","documentation":"resolve_ref only supports local JSON Schema references of the form '#/...'. A $ref that is an external URL or anchor (e.g. 'http://...', '#name') is rejected because strict-mode schema inlining cannot resolve it.","triggerScenarios":"A pydantic model (or custom schema) that emits external $refs, e.g. referencing types from another library that set external $id/$schema URLs.","commonSituations":"Models importing types from packages that declare external JSON schema ids; hand-written schemas with remote refs; pydantic v1 generating absolute-ref schemas from certain configurations.","solutions":["Remove or inline the external-referencing types into your own models","Ensure all referenced types are local pydantic v2 models so refs stay '#/$defs/...'","If hand-building a schema, replace remote refs with inlined definitions"],"exampleFix":"# before\nclass Output(BaseModel):\n    x: ExternalLibType  # emits external $ref\n# after\nclass LocalType(BaseModel):\n    ...  # copy fields locally\nclass Output(BaseModel):\n    x: LocalType","handlingStrategy":"validation","validationCode":"schema = Output.model_json_schema()\nimport json\ntext = json.dumps(schema)\nimport re\next = re.findall(r'\"\\$ref\"\\s*:\\s*\"(?!#/)', text)\nassert not ext, f\"external refs detected: {ext}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only reference local pydantic models in output types","Avoid importing types from libs that declare external JSON-schema ids"],"tags":["json-schema","refs","pydantic"],"backgroundTag":"external-schema-ref","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}