{"record":{"id":"6f7a5176b4489b3f","repo":"zed-industries/zed","slug":"unsupported-ref-format-only-defs-name-and","errorCode":null,"errorMessage":"Unsupported $ref format (only `#/$defs/<name>` and `#/definitions/<name>` are supported): {ref_str}","messagePattern":"Unsupported \\$ref format \\(only `#/\\$defs/<name>` and `#/definitions/<name>` are supported\\): (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/language_model_core/src/tool_schema.rs","lineNumber":198,"sourceCode":"                resolve_refs_recursive(item, defs, legacy_defs, visiting)?;\n            }\n        }\n        _ => {}\n    }\n    Ok(())\n}\n\n/// Parses a same-document `$ref` like `#/$defs/Foo` or `#/definitions/Foo`.\n/// Returns `(defs_key, name)` where `defs_key` is the top-level key the\n/// definition was looked up under, and `name` is the definition name.\nfn parse_ref(ref_str: &str) -> Result<(&'static str, &str)> {\n    if let Some(name) = ref_str.strip_prefix(\"#/$defs/\") {\n        return Ok((\"$defs\", name));\n    }\n    if let Some(name) = ref_str.strip_prefix(\"#/definitions/\") {\n        return Ok((\"definitions\", name));\n    }\n    anyhow::bail!(\n        \"Unsupported $ref format (only `#/$defs/<name>` and `#/definitions/<name>` are supported): {ref_str}\"\n    );\n}\n\nfn adapt_to_json_schema_subset(json: &mut Value) -> Result<()> {\n    if let Value::Object(obj) = json {\n        const UNSUPPORTED_KEYS: [&str; 4] = [\"if\", \"then\", \"else\", \"$ref\"];\n\n        for key in UNSUPPORTED_KEYS {\n            anyhow::ensure!(\n                !obj.contains_key(key),\n                \"Schema cannot be made compatible because it contains \\\"{key}\\\"\"\n            );\n        }\n\n        const KEYS_TO_REMOVE: [(&str, fn(&Value) -> bool); 6] = [\n            (\"format\", |value| value.is_string()),\n            (\"additionalProperties\", |_| true),","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/language_model_core/src/tool_schema.rs#L180-L216","documentation":"parse_ref only accepts same-document references of the exact forms #/$defs/<name> and #/definitions/<name>. Any other $ref string — external file refs like 'shared.json#/Foo', JSON-Schema-2020 anchors like '#Foo', or OpenAPI-style '#/components/schemas/Foo' — is rejected before lookup because the inliner has no way to fetch or resolve it.","triggerScenarios":"Passing a tool input_schema authored against JSON Schema 2019+ (anchor-based refs), a multi-file schema split across $id documents, or a schema converted from OpenAPI without rewriting component paths.","commonSituations":"Copy-pasting schemas from OpenAPI specs; using $defs with nested paths like '#/$defs/Foo/properties/bar' (also unsupported since only the top-level name is parsed); monorepos sharing schema files by relative path.","solutions":["Pre-process the schema with an external dereferencer (jsonschema-ref-parser, datamodel-code-generator) that produces one self-contained document","Rewrite OpenAPI '#/components/schemas/X' refs to '#/$defs/X' and hoist the components into $defs","Replace anchor-based refs with named $defs entries","After bundling, re-check for stray $ref keys — adapt_to_json_schema_subset also hard-rejects any remaining $ref"],"exampleFix":"// before\n{ \"$ref\": \"shared.json#/Point\" }\n\n// after\n{\n  \"$defs\": { \"Point\": { \"type\": \"object\", \"properties\": { \"x\": { \"type\": \"number\" }, \"y\": { \"type\": \"number\" } } } },\n  \"$ref\": \"#/$defs/Point\"\n}","handlingStrategy":"validation","validationCode":"fn only_supported_refs(schema: &serde_json::Value) -> bool {\n    let ok = true;\n    walk_refs(schema, &|r| r.starts_with(\"#/$defs/\") || r.starts_with(\"#/definitions/\"));\n    ok\n}\n// bundle first if this returns false:\n//   $RefParser.dereference(schema)  (JS)  |  jsonschema_ref_resolver (Rust)","typeGuard":"fn is_same_document_ref(ref_str: &str) -> bool {\n    ref_str.starts_with(\"#/$defs/\") || ref_str.starts_with(\"#/definitions/\")\n}","tryCatchPattern":null,"preventionTips":["Dereference external/anchor refs into a single self-contained document before passing schemas to LLM tools","Remember $ref is on the unsupported-keys list in adapt_to_json_schema_subset — the goal is full inlining","Add a schema lint step to CI for tool schemas (no external refs, no if/then/else)"],"tags":["json-schema","json-ref","llm","tools","schema-resolution"],"backgroundTag":"unsupported-json-schema-ref","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}