{"record":{"id":"6f0f0f863ce36c76","repo":"langchain-ai/deepagents","slug":"workspace-policy-and-fingerprint-must-be-configure","errorCode":null,"errorMessage":"Workspace policy and fingerprint must be configured together.","messagePattern":"Workspace policy and fingerprint must be configured together\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/client/remote_client.py","lineNumber":848,"sourceCode":"        workspace = cast(\"dict[str, Any]\", response[\"workspace\"])\n        self._workspaces[thread_id] = workspace\n        return workspace\n\n    def set_workspace(\n        self,\n        cwd: str,\n        config: Mapping[str, Any] | None = None,\n        *,\n        config_fingerprint: str | None = None,\n    ) -> None:\n        \"\"\"Configure the explicit workspace used when binding threads.\n\n        Raises:\n            ValueError: If only one policy field is provided.\n        \"\"\"\n        if (config is None) != (config_fingerprint is None):\n            msg = \"Workspace policy and fingerprint must be configured together.\"\n            raise ValueError(msg)\n        self._workspace_cwd = cwd\n        self._workspace_config = dict(config) if config is not None else None\n        self._workspace_config_fingerprint = config_fingerprint\n        self._workspaces.clear()\n\n    async def aensure_thread(self, config: dict[str, Any]) -> None:\n        \"\"\"Ensure the remote thread record exists before mutating state.\n\n        In the LangGraph dev server, checkpoint persistence and HTTP thread\n        registration are separate. After a server restart, a thread may still\n        have checkpointed state on disk while `POST /threads/{id}/state`\n        returns 404 because the server has not yet materialized that thread in\n        its live store.\n\n        This method performs the idempotent HTTP-side registration with\n        `if_exists='do_nothing'` so callers that recovered state from\n        persistence can safely follow up with `aupdate_state`.\n","sourceCodeStart":830,"sourceCodeEnd":866,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/client/remote_client.py#L830-L866","documentation":"`set_workspace` accepts an optional workspace policy `config` and its `config_fingerprint`. The two are a matched pair: the fingerprint attests to the exact policy being bound, so providing exactly one of them is ambiguous and raises this ValueError. Both or neither must be supplied.","triggerScenarios":"Calling `agent.set_workspace(cwd, config=policy)` without `config_fingerprint=...`, or `agent.set_workspace(cwd, config_fingerprint=\"...\")` without `config`, with the other argument left as None.","commonSituations":"Adding the fingerprint parameter to an existing call and forgetting the policy (or vice versa); a refactor passing the fingerprint through a variable that is sometimes None while the config is always set; copying a call example that only showed one argument.","solutions":["Pass both arguments together: `set_workspace(cwd, config=policy, config_fingerprint=fingerprint)`.","If you have no policy, call `set_workspace(cwd)` with neither argument.","Compute the fingerprint from the same policy object you pass (e.g. a stable hash of the serialized config) so they cannot diverge.","Audit call sites: if one of the two values can be None while the other is set, normalize them at the source before calling."],"exampleFix":"// before\nagent.set_workspace(\"/project\", config=policy)  # ValueError\n\n// after\nagent.set_workspace(\"/project\", config=policy, config_fingerprint=fingerprint)","handlingStrategy":"validation","validationCode":"if (config is None) != (config_fingerprint is None):\n    raise ValueError(\"Pass both config and config_fingerprint to set_workspace, or neither\")\nagent.set_workspace(cwd, config=config, config_fingerprint=config_fingerprint)","typeGuard":null,"tryCatchPattern":"try:\n    agent.set_workspace(cwd, config=policy, config_fingerprint=fingerprint)\nexcept ValueError as exc:\n    if \"configured together\" in str(exc):\n        logging.error(\"Workspace policy and fingerprint must both be set or both omitted\")\n    else:\n        raise","preventionTips":["Derive the fingerprint from the same policy object you pass, in one helper function.","Never pass the fingerprint through a variable that can independently be None.","Wrap policy binding in a single utility so the pair is always supplied together."],"tags":["configuration","validation","workspace","policy"],"backgroundTag":"incomplete-configuration","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}