{"record":{"id":"a185e44429b3b785","repo":"langchain-ai/deepagents","slug":"a-failed-write-cannot-have-changed-the-file","errorCode":null,"errorMessage":"a failed write cannot have changed the file","messagePattern":"a failed write cannot have changed the file","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/configuration/writer.py","lineNumber":47,"sourceCode":"    error: str | None = None\n\n    def __post_init__(self) -> None:\n        \"\"\"Reject outcomes that cannot describe a real transaction.\n\n        Callers branch on `ok` alone, so a failure with no detail would surface\n        as a bare \"could not be saved\" with nothing to act on, and a change\n        recorded against a failed write would report an edit that never\n        reached the file.\n\n        Raises:\n            ValueError: If the three fields do not describe one outcome.\n        \"\"\"\n        if not self.ok and self.error is None:\n            msg = \"a failed write must carry an error detail\"\n            raise ValueError(msg)\n        if self.changed and not self.ok:\n            msg = \"a failed write cannot have changed the file\"\n            raise ValueError(msg)\n        if self.ok and self.error is not None:\n            msg = \"a successful write cannot carry an error detail\"\n            raise ValueError(msg)\n\n\ndef update_user_config(\n    mutate: Callable[[dict[str, Any]], bool],\n    *,\n    config_path: Path | None = None,\n) -> WriteResult:\n    \"\"\"Serialize a read-modify-write of the user config and replace it atomically.\n\n    Writes the user tier only. The managed path is refused rather than trusted\n    to be unreachable.\n\n    A committed write to the default path also refreshes the shared process\n    resolver, so later reads see the new value. That refresh is best-effort and\n    never turns a landed write into a reported failure; see","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/configuration/writer.py#L29-L65","documentation":"WriteResult's `__post_init__` enforces that a failed write (ok=False) cannot report changed=True. If the file changed, the write partially succeeded, and claiming failure-with-change would corrupt callers' assumptions about whether the on-disk config matches the intended mutation.","triggerScenarios":"Constructing WriteResult(ok=False, changed=True, error=<msg>) — e.g. a mutate callable returned True (made changes) but the overall write path was later marked failed, or hand-building a result in tests/tooling with contradictory fields.","commonSituations":"Partial-failure handling where the mutation applied but serialization/atomic rename failed; results aggregated from multiple attempts with mixed flags; test fixtures written by copy-paste.","solutions":["If the file was actually updated, set ok=True and keep changed=True (optionally with no error)","If the write truly failed, set changed=False and describe the failure in error","For partial application, roll back or report the change via a distinct mechanism instead of contradictory flags"],"exampleFix":"// before\nWriteResult(ok=False, error=\"rename failed\", changed=True)\n// after\nWriteResult(ok=False, error=\"rename failed\", changed=False)","handlingStrategy":"validation","validationCode":"def check_write_flags(ok: bool, changed: bool) -> str | None:\n    if changed and not ok:\n        return \"failed write cannot report changed=True\"\n    return None\n\nissue = check_write_flags(ok, changed)  # check before constructing","typeGuard":"def is_consistent_write_result(ok: bool, changed: bool) -> bool:\n    return not (changed and not ok)","tryCatchPattern":"try:\n    result = WriteResult(ok=False, error=err, changed=changed)\nexcept ValueError:\n    result = WriteResult(ok=False, error=err, changed=False)","preventionTips":["Reset changed=False whenever the write path fails after mutation","Derive changed from the mutate callable's return only on success","Handle partial application explicitly instead of contradictory flags"],"tags":["invariant","configuration","file-write"],"backgroundTag":"inconsistent-write-result","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}