{"record":{"id":"6f3d95759efb03dd","repo":"aio-libs/aiohttp","slug":"none-is-not-allowed-as-password-value","errorCode":null,"errorMessage":"None is not allowed as password value","messagePattern":"None is not allowed as password value","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/client_middleware_digest_auth.py","lineNumber":206,"sourceCode":"    - RFC 1945: Section 11.1 (username restrictions)\n\n    Implementation notes:\n    The core digest calculation is inspired by the implementation in\n    https://github.com/requests/requests/blob/v2.18.4/requests/auth.py\n    with added support for modern digest auth features and error handling.\n    \"\"\"\n\n    def __init__(\n        self,\n        login: str,\n        password: str,\n        preemptive: bool = True,\n    ) -> None:\n        if login is None:\n            raise ValueError(\"None is not allowed as login value\")\n\n        if password is None:\n            raise ValueError(\"None is not allowed as password value\")\n\n        if \":\" in login:\n            raise ValueError('A \":\" is not allowed in username (RFC 1945#section-11.1)')\n\n        self._login_str: Final[str] = login\n        self._login_bytes: Final[bytes] = login.encode(\"utf-8\")\n        self._password_bytes: Final[bytes] = password.encode(\"utf-8\")\n\n        self._last_nonce_bytes = b\"\"\n        self._nonce_count = 0\n        self._challenge: DigestAuthChallenge = {}\n        self._preemptive: bool = preemptive\n        # Set of URLs defining the protection space\n        self._protection_space: list[str] = []\n        # Origin the credentials are scoped to; set on the first request.\n        self._origin: URL | None = None\n\n    async def _encode(self, method: str, url: URL, body: Payload | Literal[b\"\"]) -> str:","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/client_middleware_digest_auth.py#L188-L224","documentation":"Raised by DigestAuthMiddleware.__init__ when password is None. Mirrors the login check: the password is encoded to bytes immediately, so a None value would AttributeError later; the constructor rejects it up front.","triggerScenarios":"Constructing DigestAuthMiddleware(login='user', password=None). Most often the result of an env var or secret lookup returning None and being forwarded.","commonSituations":"Password secret not loaded (key name typo, vault path wrong). Default of None on a CLI flag. Asymmetric config where username is set but password is not.","solutions":["Provide a concrete password string (empty string '' is accepted if you genuinely mean empty).","Load via a secret manager that errors on missing keys instead of returning None.","Validate both credentials together at the config boundary."],"exampleFix":"// before\nmw = DigestAuthMiddleware(login='user', password=os.getenv('API_PASS'))\n// after\nimport os\nmw = DigestAuthMiddleware(login='user', password=os.environ['API_PASS'])","handlingStrategy":"validation","validationCode":"def require_password(password):\n    if password is None:\n        raise ValueError('password is required')\n    return password\n\nDigestAuthMiddleware(login=login, password=require_password(password))","typeGuard":"def is_nonnull_password(v) -> bool:\n    return v is not None and isinstance(v, str)","tryCatchPattern":"try:\n    mw = DigestAuthMiddleware(login=login, password=password)\nexcept ValueError as e:\n    if 'password' in str(e):\n        raise SystemExit('API password not configured')\n    raise","preventionTips":["Read secrets via a manager that raises on missing values.","Validate both credentials together at config load.","Never forward optional config values directly into auth constructors."],"tags":["authentication","digest-auth","validation","configuration"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}