{"record":{"id":"167d920b579f615a","repo":"infiniflow/ragflow","slug":"credential-item-name-was-not-found","errorCode":null,"errorMessage":"Credential item {name=} was not found","messagePattern":"Credential item (.+?) was not found","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"common/data_source/imap_connector.py","lineNumber":204,"sourceCode":"        The `imaplib.IMAP4_SSL` object is supposed to be an \"ephemeral\" object; it's not something that you can login,\n        logout, then log back into again. I.e., the following will fail:\n\n        ```py\n        mail_client.login(..)\n        mail_client.logout();\n        mail_client.login(..)\n        ```\n\n        Therefore, you need a fresh, new instance in order to operate with IMAP. This function gives one to you.\n\n        # Notes\n        This function will throw an error if the credentials have not yet been set.\n        \"\"\"\n\n        def get_or_raise(name: str) -> str:\n            value = self.credentials.get(name)\n            if not value:\n                raise RuntimeError(f\"Credential item {name=} was not found\")\n            if not isinstance(value, str):\n                raise RuntimeError(f\"Credential item {name=} must be of type str, instead received {type(name)=}\")\n            return value\n\n        username = get_or_raise(_USERNAME_KEY)\n        password = get_or_raise(_PASSWORD_KEY)\n\n        mail_client = imaplib.IMAP4_SSL(host=self._host, port=self._port)\n        status, _data = mail_client.login(user=username, password=password)\n\n        if status != _IMAP_OKAY_STATUS:\n            raise RuntimeError(f\"Failed to log into imap server; {status=}\")\n\n        return mail_client\n\n    def _load_from_checkpoint(\n        self,\n        start: SecondsSinceUnixEpoch,","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/imap_connector.py#L186-L222","documentation":"Raised by the nested get_or_raise helper inside ImapConnector._get_mail_client when the credentials dict has no value for _USERNAME_KEY or _PASSWORD_KEY (missing key, None, or empty string). It means load_credentials was never called, was called with an incomplete dict, or the dict keys do not match the expected names. It surfaces as a RuntimeError before any network activity.","triggerScenarios":"Calling _get_mail_client() (directly or via _load_from_checkpoint) on an ImapConnector whose credentials dict lacks the username or password entry - e.g. constructing the connector and immediately triggering a sync, or passing a dict with keys like 'user'/'pass' instead.","commonSituations":"Skipping the connector lifecycle load_credentials step; a credential refresh that rewrote the dict and dropped one field; per-user connector config saved with an empty password field in the UI.","solutions":["Call load_credentials with both required keys (username and password) before any operation that opens a mail client.","Inspect the exact keys expected (_USERNAME_KEY / _PASSWORD_KEY constants at the top of common/data_source/imap_connector.py) and align your dict names to them.","If credentials come from a store, verify both fields were persisted for this user/instance and are non-empty strings.","Add a startup assertion in your orchestration code that fails fast with a clear message before the connector runs."],"exampleFix":"# before\nconnector = ImapConnector(host='imap.example.com', port=993, credentials={'username': 'a@b.com'})\ndocs = connector.load_from_checkpoint(start, end, checkpoint)  # RuntimeError: name='password' not found\n\n# after\nconnector = ImapConnector(host='imap.example.com', port=993, credentials={'username': 'a@b.com', 'password': os.environ['IMAP_PASSWORD']})\ndocs = connector.load_from_checkpoint(start, end, checkpoint)","handlingStrategy":"validation","validationCode":"def imap_credentials_complete(credentials: dict) -> bool:\n    return all(\n        isinstance(credentials.get(k), str) and credentials.get(k)\n        for k in ('username', 'password')\n    )","typeGuard":"from typing import Any\n\ndef has_str_credentials(creds: dict[str, Any], *keys: str) -> bool:\n    return all(isinstance(creds.get(k), str) and creds[k].strip() for k in keys)","tryCatchPattern":"try:\n    connector.load_from_checkpoint(start, end, checkpoint)\nexcept RuntimeError as e:\n    if 'was not found' in str(e):\n        raise RuntimeError('IMAP credentials incomplete; re-run load_credentials with username+password') from e\n    raise","preventionTips":["Centralize credential construction in one factory that asserts required keys.","Treat empty-string credential fields as missing at the UI/config layer, not inside the connector.","Log credential dict keys (names only, never values) at load time to catch mismatches early."],"tags":["imap","email","credentials","connector"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}