{"record":{"id":"6eeb30079a89520e","repo":"reflex-dev/reflex","slug":"root-state-must-be-provided-to-convert-legacy-toke","errorCode":null,"errorMessage":"Root state must be provided to convert legacy token to BaseStateToken.","messagePattern":"Root state must be provided to convert legacy token to BaseStateToken\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"reflex/istate/manager/token.py","lineNumber":233,"sourceCode":"        The legacy token format is \"{ident}_{module_path}.{class_name}\".\n\n        Args:\n            legacy_token: The legacy token string to convert.\n            root_state: The root state instance.\n\n        Returns:\n            A BaseStateToken instance created from the legacy token.\n\n        Raises:\n            ValueError: If the legacy token format is invalid or if the state class cannot be found\n        \"\"\"\n        from reflex.state import _split_substate_key\n\n        if root_state is None:\n            msg = (\n                \"Root state must be provided to convert legacy token to BaseStateToken.\"\n            )\n            raise ValueError(msg)\n\n        console.deprecate(\n            feature_name=\"Passing a string to modify_state\",\n            reason=\"Use rx.BaseStateToken(token, state_cls) instead of the legacy string format\",\n            deprecation_version=\"0.9.0\",\n            removal_version=\"1.0\",\n        )\n\n        client_token, state_path = _split_substate_key(legacy_token)\n        state_cls = root_state.get_class_substate(tuple(state_path.split(\".\")))  # type: ignore[union-attr]\n        return cls(ident=client_token, cls=state_cls)\n","sourceCodeStart":215,"sourceCodeEnd":245,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/reflex/istate/manager/token.py#L215-L245","documentation":"BaseStateToken.from_legacy_token converts an old-style string token into a BaseStateToken and needs the root state class to resolve substate names — without it there is no way to look up state classes, so it raises ValueError. It also emits a deprecation warning because passing plain strings to modify_state is deprecated (removal in 1.0).","triggerScenarios":"Calling from_legacy_token(token_string, root_state=None), most often indirectly via modify_state(\"token_string\") without a state class so no root can be inferred. Custom middleware that stored string tokens and calls the conversion with only the string hits this directly.","commonSituations":"Upgrading an app/session layer that persisted legacy string tokens; middleware or auth code that calls modify_state with a raw token string and no state_cls; mixing pre-0.9 token formats with the new BaseStateToken API.","solutions":["Pass a state class alongside the token: modify_state(token_string, rx.BaseState) or provide root_state to from_legacy_token","Better: migrate to rx.BaseStateToken(token, StateCls) instead of the legacy string format before 1.0","If wrapping modify_state generically, thread the state_cls/root_state through your abstraction"],"exampleFix":"# before\nasync with state.modify_state(\"legacy_token_string\") as state:\n    ...\n\n# after\nasync with state.modify_state(BaseStateToken(\"legacy_token_string\", rx.BaseState)) as state:\n    ...","handlingStrategy":"validation","validationCode":"if isinstance(token, str) and root_state is None:\n    raise ValueError(\"legacy string token requires a state class\")  # fail fast with a clear message","typeGuard":"def is_legacy_string_token(token: object) -> TypeGuard[str]:\n    return isinstance(token, str)","tryCatchPattern":null,"preventionTips":["Migrate stored tokens to BaseStateToken before the 1.0 removal","Always pass a state class when using string tokens: modify_state(token_str, rx.BaseState)","Watch for the deprecation warning in CI to catch remaining legacy call sites"],"tags":["reflex","deprecation","token-migration","state"],"backgroundTag":"deprecated-api-migration","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}