{"record":{"id":"b2d5f6f539964f71","repo":"langchain-ai/deepagents","slug":"a-successful-write-cannot-carry-an-error-detail","errorCode":null,"errorMessage":"a successful write cannot carry an error detail","messagePattern":"a successful write cannot carry an error detail","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/configuration/writer.py","lineNumber":50,"sourceCode":"        \"\"\"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\n    `refresh_shared_resolver`.\n\n    Args:","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/configuration/writer.py#L32-L68","documentation":"WriteResult's `__post_init__` enforces that a successful write (ok=True) must not carry an `error` detail. An error attached to a success would mislead callers and UIs that surface errors to users, so the combination is rejected at construction.","triggerScenarios":"Constructing WriteResult(ok=True, error=<msg>, ...) — e.g. code that always sets error from a previous attempt's exception without clearing it on retry success, or hand-built results in tests.","commonSituations":"Retry loops that keep the first attempt's exception object while succeeding on the second; copying a failed result and flipping ok to True; tests with fixture objects that include a leftover error message.","solutions":["Set error=None when ok=True (the default)","On successful retry, construct a fresh WriteResult instead of mutating/reusing the failed one","Surface non-fatal warnings through a separate channel, not the error field"],"exampleFix":"// before\nWriteResult(ok=True, error=\"previous attempt timed out\", changed=True)\n// after\nWriteResult(ok=True, error=None, changed=True)","handlingStrategy":"validation","validationCode":"def check_write_flags(ok: bool, error: str | None) -> str | None:\n    if ok and error is not None:\n        return \"successful write must not carry an error detail\"\n    return None\n\nissue = check_write_flags(ok, err)  # check before constructing","typeGuard":"def is_clean_success(ok: bool, error: str | None) -> bool:\n    return not ok or error is None","tryCatchPattern":"try:\n    result = WriteResult(ok=True, error=stale_error, changed=True)\nexcept ValueError:\n    result = WriteResult(ok=True, error=None, changed=True)","preventionTips":["Construct a fresh WriteResult on retry success; never mutate the failed one","Default error to None and only set it on the failure branch","Report warnings via a dedicated field or logging, not error"],"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"}