{"record":{"id":"e6d815b34c5f1241","repo":"spring-projects/spring-ai","slug":"context-does-not-have-an-entry-for-key-s-e6d815","errorCode":null,"errorMessage":"Context does not have an entry for key [%s]","messagePattern":"Context does not have an entry for key \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-model/src/main/java/org/springframework/ai/model/MutableResponseMetadata.java","lineNumber":75,"sourceCode":"\t * @return the previous value associated with the key, or null if there was no mapping\n\t * for the key\n\t */\n\tpublic Object remove(Object key) {\n\t\treturn this.map.remove(key);\n\t}\n\n\t/**\n\t * Gets an entry from the context. Throws exception when entry is not present.\n\t * @param key key\n\t * @param <T> value type\n\t * @throws IllegalArgumentException if not present\n\t * @return entry\n\t */\n\t@Override\n\tpublic <T> T getRequired(Object key) {\n\t\tT object = (T) this.map.get(key);\n\t\tif (object == null) {\n\t\t\tthrow new IllegalArgumentException(\"Context does not have an entry for key [\" + key + \"]\");\n\t\t}\n\t\treturn object;\n\t}\n\n\t/**\n\t * Checks if context contains a key.\n\t * @param key key\n\t * @return {@code true} when the context contains the entry with the given key\n\t */\n\t@Override\n\tpublic boolean containsKey(Object key) {\n\t\treturn this.map.containsKey(key);\n\t}\n\n\t/**\n\t * Returns an element or default if not present.\n\t * @param key key\n\t * @param defaultObject default object to return","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-model/src/main/java/org/springframework/ai/model/MutableResponseMetadata.java#L57-L93","documentation":"MutableResponseMetadata.getRequired(key) returns the value for a metadata key and throws IllegalArgumentException if the key is absent or null. It is the mutable counterpart of AbstractResponseMetadata.getRequired and carries the same requirement contract.","triggerScenarios":"Calling getRequired on a mutable metadata map that was never populated with that key — e.g. reading a key before the framework/put() populated it, or using a key the upstream model response never contained.","commonSituations":"Code that builds or mutates response metadata itself and forgets a put() for the required key; reading metadata mid-pipeline before an enriching step ran; typos in key names.","solutions":["Ensure put(key, value) is called with the exact key before getRequired is invoked","Guard with containsKey(key) or fall back to get(key) when the value is optional","Log/inspect the metadata map contents (keySet()) to confirm the key name and population timing"],"exampleFix":"// before\nString id = metadata.getRequired(\"request-id\");\n// after\nString id = metadata.containsKey(\"request-id\")\n    ? metadata.getRequired(\"request-id\")\n    : UUID.randomUUID().toString();","handlingStrategy":"try-catch","validationCode":"if (mutableMetadata == null || !mutableMetadata.containsKey(key)) {\n    throw new IllegalStateException(\"Key not populated before read: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n    T value = mutableMetadata.getRequired(key);\n} catch (IllegalArgumentException e) {\n    // key not set yet — initialize or skip\n    mutableMetadata.put(key, initialValue);\n    T value = initialValue;\n}","preventionTips":["Ensure every required key is put() before the metadata is consumed","Read metadata only after the enrichment/population step completes","Verify key spelling against the constant used at write time"],"tags":["metadata","missing-key","illegal-argument","mutable-state"],"backgroundTag":"missing-required-argument","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}