{"record":{"id":"af5be3f4e6484ea9","repo":"langchain-ai/deepagents","slug":"namespace-component-at-index-i-contains-disallow","errorCode":null,"errorMessage":"Namespace component at index {i} contains disallowed characters: {component!r}. Only alphanumeric characters, hyphens, underscores, dots, @, +, colons, and tildes are allowed.","messagePattern":"Namespace component at index (.+?) contains disallowed characters: (.+?)\\. Only alphanumeric characters, hyphens, underscores, dots, @, \\+, colons, and tildes are allowed\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/store.py","lineNumber":85,"sourceCode":"            empty strings, or strings with disallowed characters.\n    \"\"\"\n    if not namespace:\n        msg = \"Namespace tuple must not be empty.\"\n        raise ValueError(msg)\n\n    for i, component in enumerate(namespace):\n        if not isinstance(component, str):\n            msg = f\"Namespace component at index {i} must be a string, got {type(component).__name__}.\"\n            raise TypeError(msg)\n        if not component:\n            msg = f\"Namespace component at index {i} must not be empty.\"\n            raise ValueError(msg)\n        if not _NAMESPACE_COMPONENT_RE.match(component):\n            msg = (\n                f\"Namespace component at index {i} contains disallowed characters: {component!r}. \"\n                f\"Only alphanumeric characters, hyphens, underscores, dots, @, +, colons, and tildes are allowed.\"\n            )\n            raise ValueError(msg)\n\n    return namespace\n\n\nclass StoreBackend(BackendProtocol):\n    \"\"\"Backend that stores files in LangGraph's BaseStore (persistent).\n\n    Uses LangGraph's Store for persistent, cross-conversation storage.\n    Files are organized via namespaces and persist across all threads.\n\n    Files are scoped by the caller-supplied `namespace` factory (e.g. per-user\n    or per-assistant isolation).\n    \"\"\"\n\n    def __init__(\n        self,\n        *,\n        namespace: NamespaceFactory,","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/store.py#L67-L103","documentation":"StoreBackend namespaces are tuples of string components that become LangGraph BaseStore namespace prefixes. `_validate_namespace` rejects any component containing characters outside the allowed set (alphanumeric, `-`, `_`, `.`, `@`, `+`, `:`, `~`) so persisted store keys stay unambiguous and portable. A non-string component also fails the regex check and raises this ValueError.","triggerScenarios":"Passing a namespace tuple with components containing spaces, slashes, `*`, `?`, non-ASCII characters, or non-string values (e.g. ints, None) either directly to `StoreBackend(store=..., namespace=...)`, via a namespace factory callable, or by constructing a StoreBackend subclass with a bad default namespace.","commonSituations":"Building a namespace from user input or file paths without sanitizing (`/tmp/x` contains `/`); interpolating ints (`(123,)` instead of `('123',)`); joining namespace parts with `/` instead of keeping them as separate tuple elements.","solutions":["Sanitize each namespace component to the allowed character set before constructing the StoreBackend","Coerce non-string values with str() and strip or replace disallowed characters (e.g. replace `/` with `-`)","Split path-like values into separate tuple components instead of embedding `/` in one component","Catch the ValueError to surface a clear configuration error at startup rather than at first store access"],"exampleFix":"// before\nbackend = StoreBackend(store=store, namespace=lambda rt: (f\"files/{rt.context['user']}\",))\n// after\nuser = str(rt.context['user']).replace('/', '-').replace(' ', '_')\nbackend = StoreBackend(store=store, namespace=lambda rt: ('files', user))","handlingStrategy":"validation","validationCode":"import re\n_COMPONENT_RE = re.compile(r'^[A-Za-z0-9._@+:~-]+$')\ndef valid_namespace(namespace) -> bool:\n    return (\n        isinstance(namespace, tuple)\n        and all(isinstance(c, str) and _COMPONENT_RE.match(c) for c in namespace)\n    )\nif not valid_namespace(ns):\n    raise ValueError(f'invalid namespace: {ns!r}')\nbackend = StoreBackend(store=store, namespace=ns)","typeGuard":"def is_valid_namespace(namespace: object) -> bool:\n    import re\n    return (\n        isinstance(namespace, tuple)\n        and all(\n            isinstance(c, str)\n            and re.fullmatch(r'[A-Za-z0-9._@+:~-]+', c) is not None\n            for c in namespace\n        )\n    )","tryCatchPattern":null,"preventionTips":["Build namespaces from sanitized ids, never raw paths or user input","Keep path-like segments as separate tuple elements instead of embedding '/'","Coerce to str explicitly (str(user_id)) before forming the tuple","Validate namespaces at construction/startup, not at first store access"],"tags":["validation","namespace","store"],"backgroundTag":"invalid-namespace-component","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}