{"record":{"id":"47d23b52ba8d3aa6","repo":"langchain-ai/deepagents","slug":"type-helper-name-exposes-no-name-r-slot","errorCode":null,"errorMessage":"{type(helper).__name__} exposes no {name!r} slot, so dcode cannot {purpose}. The SDK's summarization internals have changed.","messagePattern":"(.+?) exposes no (.+?) slot, so dcode cannot (.+?)\\. The SDK's summarization internals have changed\\.","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/offload_middleware.py","lineNumber":154,"sourceCode":"    nothing reads, leaving the SDK's own behavior in place -- a silent no-op\n    that reports nothing. Checking first turns that into a loud failure.\n\n    Args:\n        helper: The SDK summarization helper being patched.\n        name: Attribute dcode is about to overwrite.\n        purpose: What dcode loses if the slot is gone, phrased to follow\n            \"so dcode cannot ...\".\n\n    Raises:\n        AttributeError: If the SDK no longer exposes the named slot.\n    \"\"\"\n    if hasattr(helper, name):\n        return\n    msg = (\n        f\"{type(helper).__name__} exposes no {name!r} slot, so dcode cannot \"\n        f\"{purpose}. The SDK's summarization internals have changed.\"\n    )\n    raise AttributeError(msg)\n\n\ndef _install_summary_model_retries(\n    summarization: SummarizationMiddleware,\n    model: BaseChatModel | None = None,\n) -> None:\n    \"\"\"Replace LangChain's generic summary retries with dcode's exact policy.\n\n    Also selects the model summaries are generated with, which is the only\n    place a `--summarization-model` override takes effect.\n\n    Args:\n        summarization: Middleware whose summary-model slot is replaced.\n        model: Model to generate summaries with. `None` reuses\n            `summarization.model`, the model driving thresholds and counting.\n    \"\"\"\n    helper = summarization._lc_helper\n    # A renamed slot would leave LangChain's unconditional three-attempt","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/offload_middleware.py#L136-L172","documentation":"dcode installs retry, trim-limit, token-counter, and lazy-model behavior onto LangChain's `SummarizationMiddleware` internals via private attribute slots. `_require_helper_slot` verifies a private attribute exists before patching; when the helper class no longer exposes the expected slot, it raises AttributeError naming the missing slot. This means the pinned SDK's summarization implementation changed shape and dcode's monkeypatching can no longer proceed safely.","triggerScenarios":"Raising an SDK pin (`deepagents` / langchain SummarizationMiddleware) to a version that renamed or removed private attributes targeted by `_install_summary_model_retries`, `_install_summary_trim_limit`, `_install_summary_token_counter`, or `_install_lazy_summary_model`.","commonSituations":"Upgrading `deepagents` in pyproject without updating offload_middleware internals; using a fork or prerelease SDK with refactored summarization classes; running dcode-dev against a workspace SDK newer than the pin.","solutions":["Pin the `deepagents` version dcode expects (exact pin in libs/code pyproject.toml).","Update dcode's `_install_*` helpers to the new private attribute names in the upgraded SDK, then bump the pin in the same PR.","Clear stale installs: reinstall dcode so the editable/installed SDK matches the pin."],"exampleFix":"// before: patching a renamed slot\n_install_summary_token_counter(summarization, counter)  # AttributeError\n// after: guard or update to the new slot name\nif hasattr(summarization, \"_token_counter_new\"):\n    setattr(summarization, \"_token_counter_new\", counter)","handlingStrategy":"type-guard","validationCode":"for slot in (\"_model\", \"_trim_tokens\", \"_token_counter\"):\n    assert hasattr(summarization, slot), f\"{type(summarization).__name__} missing {slot!r}\"\nassert deepagents_version == pinned_version, \"SDK drift vs dcode pin\"","typeGuard":"def supports_summarization_slots(helper: object, slots: tuple[str, ...]) -> bool:\n    return all(hasattr(helper, s) for s in slots)","tryCatchPattern":"try:\n    install_summary_helpers(summarization)\nexcept AttributeError as e:\n    if \"exposes no\" in str(e):\n        raise SdkPinMismatch(str(e)) from e  # surface pin drift, not a crash","preventionTips":["Keep the exact `deepagents==X.Y.Z` pin and bump it in the same PR as any internal-slot change.","Add a canary test asserting the private slots exist on SummarizationMiddleware.","Avoid editable installs against mismatched workspace SDKs in dev."],"tags":["version-compatibility","sdk-internals","monkeypatch","attributeerror"],"backgroundTag":"sdk-internals-changed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}