{"record":{"id":"dfbcac319769aa1a","repo":"PrefectHQ/fastmcp","slug":"elicitation-responses-must-be-serializable-as-a-js","errorCode":null,"errorMessage":"Elicitation responses must be serializable as a JSON object (dict). Received: {result.content!r}","messagePattern":"Elicitation responses must be serializable as a JSON object \\(dict\\)\\. Received: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/client/elicitation.py","lineNumber":78,"sourceCode":"                params.message,\n                response_type,\n                params,\n                context,  # ty: ignore[invalid-argument-type]\n            )\n            # if the user returns data, we assume they've accepted the elicitation\n            if not isinstance(result, ElicitResult):\n                result = ElicitResult(action=\"accept\", content=result)\n            content = to_jsonable_python(result.content)\n            if not isinstance(content, dict | None):\n                # Auto-wrap scalar values for ScalarElicitationType schemas\n                # (single \"value\" property). This lets handlers return T directly\n                # for ctx.elicit(\"msg\", str/int/float/bool).\n                if isinstance(params, ElicitRequestFormParams) and set(\n                    params.requested_schema.get(\"properties\", {}).keys()\n                ) == {\"value\"}:\n                    content = {\"value\": content}\n                else:\n                    raise ValueError(\n                        \"Elicitation responses must be serializable as a JSON object (dict). Received: \"\n                        f\"{result.content!r}\"\n                    )\n            return MCPElicitResult(\n                _meta=result.meta,  # type: ignore[call-arg]  # _meta is Pydantic alias for meta field\n                action=result.action,\n                content=content,\n            )\n\n        except Exception as e:\n            return mcp_types.ErrorData(\n                code=mcp_types.INTERNAL_ERROR,\n                message=str(e),\n            )\n\n    return _elicitation_handler\n","sourceCodeStart":60,"sourceCodeEnd":95,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/client/elicitation.py#L60-L95","documentation":"MCP elicitation responses must be a JSON-serializable dict (object). When an elicitation handler returns a bare scalar (str/int/float/bool) for a schema that is not the special single-`value`-property form case, FastMCP raises this ValueError because it cannot wrap the content into an MCP ElicitResult. The repr of the offending content is included.","triggerScenarios":"An `elicitation_handler` returning e.g. `\"yes\"` or `42` while the request's requested_schema has properties other than a single `value` property.","commonSituations":"Handlers written for simple string elicitations reused on structured schemas; returning raw user input without wrapping it in the schema's property names.","solutions":["Return a dict whose keys match the requested_schema properties, e.g. {\"confirm\": True}","If the schema is the single-`value` form case, return the bare scalar and it is auto-wrapped","Inspect params.requested_schema in the handler to build the correct response shape"],"exampleFix":"// before\ndef handler(message, params):\n    return \"yes\"  # ValueError\n\n// after\ndef handler(message, params):\n    return {\"value\": \"yes\"}  # or keys matching requested_schema properties","handlingStrategy":"validation","validationCode":"def valid_elicitation_response(content, params) -> bool:\n    if isinstance(content, dict):\n        return True\n    props = set(params.requested_schema.get(\"properties\", {}).keys())\n    return props == {\"value\"} and isinstance(content, (str, int, float, bool))","typeGuard":"def is_json_object(content: object) -> TypeGuard[dict]:\n    return isinstance(content, dict)","tryCatchPattern":"try:\n    ...  # handler runs during elicitation\nexcept ValueError as e:\n    if \"serializable as a JSON object\" in str(e):\n        logger.error(\"elicitation handler must return a dict: %r\", e)\n    raise","preventionTips":["Always return dicts keyed by requested_schema properties","Return bare scalars only for single-`value` schemas","Test elicitation handlers against the actual requested schemas"],"tags":["python","elicitation","validation","json"],"backgroundTag":"elicitation-response-not-serializable","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}