{"record":{"id":"e1ec9841e2825f9b","repo":"microsoft/qlib","slug":"the-operator-0-is-not-registered","errorCode":null,"errorMessage":"The operator [{0}] is not registered","messagePattern":"The operator \\[(.+?)\\] is not registered","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"qlib/data/ops.py","lineNumber":1663,"sourceCode":"        \"\"\"\n        for _operator in ops_list:\n            if isinstance(_operator, dict):\n                _ops_class, _ = get_callable_kwargs(_operator)\n            else:\n                _ops_class = _operator\n\n            if not issubclass(_ops_class, (Expression,)):\n                raise TypeError(\"operator must be subclass of ExpressionOps, not {}\".format(_ops_class))\n\n            if _ops_class.__name__ in self._ops:\n                get_module_logger(self.__class__.__name__).warning(\n                    \"The custom operator [{}] will override the qlib default definition\".format(_ops_class.__name__)\n                )\n            self._ops[_ops_class.__name__] = _ops_class\n\n    def __getattr__(self, key):\n        if key not in self._ops:\n            raise AttributeError(\"The operator [{0}] is not registered\".format(key))\n        return self._ops[key]\n\n\nOperators = OpsWrapper()\n\n\ndef register_all_ops(C):\n    \"\"\"register all operator\"\"\"\n    logger = get_module_logger(\"ops\")\n\n    from qlib.data.pit import P, PRef  # pylint: disable=C0415\n\n    Operators.reset()\n    Operators.register(OpsList + [P, PRef])\n\n    if getattr(C, \"custom_ops\", None) is not None:\n        Operators.register(C.custom_ops)\n        logger.debug(\"register custom operator {}\".format(C.custom_ops))","sourceCodeStart":1645,"sourceCodeEnd":1681,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/data/ops.py#L1645-L1681","documentation":"Raised by OpsWrapper.__getattr__ (qlib/data/ops.py) when an expression string references an operator name that is not in the Operators registry. Qlib parses expression strings like \"Ref($close, 5)\" by looking up each capitalized token as an attribute of Operators; unknown names produce this AttributeError with the exact operator name in brackets.","triggerScenarios":"Evaluating an expression containing a typo or unregistered operator, e.g. \"Reff($close, 5)\" (extra f), \"EMA($close, 5)\" if not registered, or a custom operator used before calling Operators.register_custom_ops.","commonSituations":"Typos in hand-written feature strings; using a custom operator in a config before registering it in the same process; operators available only in newer qlib versions (version drift between docs and installed package); case errors (e.g. \"mean\" instead of \"Mean\").","solutions":["Check the operator name spelling and capitalization against qlib.data.ops (e.g. Ref, Mean, Std, Rank, Corr).","If it is a custom operator, call Operators.register_custom_ops([MyOp]) before parsing/evaluating expressions in this process.","Upgrade or align qlib to the version whose operator set includes the name you are using.","Print sorted(Operators._ops.keys()) to see every currently registered operator name."],"exampleFix":"# before\nfields = [\"Reff($close, 5)\"]  # typo: unknown operator\n\n# after\nfields = [\"Ref($close, 5)\"]","handlingStrategy":"validation","validationCode":"known = set(Operators._ops.keys())\ntokens = extract_operator_names(expr)  # your parser: leading capitalized tokens\nunknown = tokens - known\nif unknown:\n    raise NameError(f\"unregistered operators: {sorted(unknown)}\")","typeGuard":"def all_operators_registered(expr: str) -> bool:\n    return extract_operator_names(expr) <= set(Operators._ops.keys())","tryCatchPattern":"try:\n    D.features(insts, [expr], start, end)\nexcept AttributeError as e:\n    if \"is not registered\" in str(e):\n        # surface actionable message with registered op list\n        raise RuntimeError(f\"{e}; registered ops: {sorted(Operators._ops)}\") from e\n    raise","preventionTips":["Register all custom operators once at process start, before any qlib.init data access.","Keep feature-name lists in one module and lint them against Operators._ops in CI."],"tags":["qlib","expression","operators","registry"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}