{"record":{"id":"323450cd6beba7c2","repo":"Lightning-AI/pytorch-lightning","slug":"please-return-your-outputs-as-a-dictionary-found","errorCode":null,"errorMessage":"Please, return your outputs as a dictionary. Found {output}","messagePattern":"Please, return your outputs as a dictionary\\. Found (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/serve/servable_module_validator.py","lineNumber":170,"sourceCode":"        # Note: This isn't the original version, but a copy.\n        servable_model.eval()\n\n        @app.get(\"/ping\")\n        def ping() -> bool:\n            return True\n\n        @app.post(\"/serve\")\n        async def serve(payload: dict = Body(...)) -> dict[str, Any]:\n            body = payload[\"body\"]\n\n            for key, deserializer in deserializers.items():\n                body[key] = deserializer(body[key])\n\n            with torch.no_grad():\n                output = servable_model.serve_step(**body)\n\n            if not isinstance(output, dict):\n                raise Exception(f\"Please, return your outputs as a dictionary. Found {output}\")\n\n            for key, serializer in serializers.items():\n                output[key] = serializer(output[key])\n\n            return output\n\n        run(app, host=host, port=port, log_level=\"error\")\n","sourceCodeStart":152,"sourceCodeEnd":178,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/serve/servable_module_validator.py#L152-L178","documentation":"Inside the spawned server, after deserializing the request body, servable_model.serve_step(**body) must return a dict so outputs can be matched with output serializers by key. If it returns a tensor, list, or tuple, a generic Exception is raised in the request handler.","triggerScenarios":"serve_step returns self(x) (a raw Tensor), a tuple of tensors, or None instead of a dict keyed by output names.","commonSituations":"Reusing predict_step code that returns a bare tensor; returning multiple outputs as a tuple and expecting positional serialization.","solutions":["Change serve_step to return a dict whose keys match configure_serialization's output serializer names, e.g. {\"output\": result}","For multiple outputs return {\"logits\": ..., \"probs\": ...} with matching serializers"],"exampleFix":"# before\ndef serve_step(self, **kwargs):\n    return self(kwargs[\"x\"])\n// after\ndef serve_step(self, **kwargs):\n    return {\"output\": self(kwargs[\"x\"])}","handlingStrategy":"type-guard","validationCode":"out = model.serve_step(**model.configure_payload()[\"body\"])\nassert isinstance(out, dict), f\"serve_step must return a dict, got {type(out)}\"","typeGuard":"def returns_dict_serve_step(model, body) -> bool:\n    with torch.no_grad():\n        return isinstance(model.serve_step(**body), dict)","tryCatchPattern":null,"preventionTips":["Make serve_step always return {name: value}","Keep serializer keys in sync with serve_step output keys via a shared constant"],"tags":["lightning","serving","return-type","contract"],"backgroundTag":"invalid-return-type","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}