{"record":{"id":"abaa3c87b67694ae","repo":"NationalSecurityAgency/ghidra","slug":"object-proxy-has-neither-id-nor-path","errorCode":null,"errorMessage":"Object/proxy has neither id nor path!: {}","messagePattern":"Object/proxy has neither id nor path!: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py","lineNumber":781,"sourceCode":"        return Lifespan(msg.min, msg.max)\n\n    @staticmethod\n    def _write_obj_spec(to: bufs.ObjSpec, obj: Union[\n            str, int, DetachedObject, TraceObject]) -> None:\n        if isinstance(obj, int):\n            to.id = obj\n        elif isinstance(obj, str):\n            to.path.path = obj\n        elif isinstance(obj, DetachedObject):\n            to.id = obj.id\n        elif isinstance(obj.id, int):\n            to.id = obj.id\n        elif isinstance(obj.id, RemoteResult) and obj.id.done():\n            to.id = obj.id.result()\n        elif isinstance(obj.path, str):\n            to.path.path = obj.path\n        else:\n            raise ValueError(\n                \"Object/proxy has neither id nor path!: {}\".format(obj))\n\n    @staticmethod\n    def _read_obj_desc(msg: bufs.ObjDesc) -> DetachedObject:\n        return DetachedObject(msg.id, msg.path.path)\n\n    @staticmethod\n    def _write_value(to: bufs.Value, value: Any,\n                     schema: Optional[sch.Schema] = None) -> None:\n        if value is None:\n            to.null_value.SetInParent()\n            return\n        elif isinstance(value, bool):\n            to.bool_value = value\n            return\n        elif isinstance(value, int):\n            if schema == sch.BYTE:\n                to.byte_value = value","sourceCodeStart":763,"sourceCodeEnd":799,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py#L763-L799","documentation":"Raised by Client._write_obj_desc() when serializing an object reference and none of the recognized cases matched: the value is not an int, str, DetachedObject, a TraceObject with an int id, a resolved RemoteResult id, or a TraceObject with a str path. Essentially the object carries neither a usable id nor a usable path, so it cannot be written to the wire.","triggerScenarios":"A TraceObject whose id is an unresolved Future and whose path is None; a DetachedObject constructed with non-int id and non-str path; passing an arbitrary object where an object reference was expected.","commonSituations":"Using a TraceObject before its id/path has been resolved (e.g. a Future that has not completed), version skew, or hand-built mock objects in tests.","solutions":["Ensure the object has at least one concrete identifier (resolved id or path) before it is sent.","Resolve any pending Future id first (call .result()) or use from_path() to guarantee a path.","Construct objects only via the factory helpers (proxy_object/from_id/from_path) rather than directly."],"exampleFix":"// before\nobj = trace.proxy_object(id=fut)  # fut is an unresolved Future\n// after\nobj = trace.proxy_object(id=fut.result())  # resolve first, or pass a path","handlingStrategy":"validation","validationCode":"def obj_has_ref(o) -> bool:\n    return (getattr(o, 'id', None) is not None and not isinstance(o.id, type(None))) \\\n        or getattr(getattr(o, 'path', None), 'path', None)\nif not obj_has_ref(obj):\n    raise ValueError('object has neither resolved id nor path')","typeGuard":"def is_writable_obj_ref(o) -> bool:\n    import concurrent.futures as cf\n    oid = getattr(o, 'id', None)\n    if isinstance(oid, int): return True\n    if isinstance(oid, cf.Future) and oid.done(): return True\n    if isinstance(getattr(o, 'path', None), str) or getattr(getattr(o,'path',None),'path',None): return True\n    return False","tryCatchPattern":null,"preventionTips":["Resolve Future ids before sending.","Always construct objects via the factory helpers."],"tags":["internal","trace-rmi","serialization","object-model"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}