infiniflow/ragflow · error · ConnectorMissingCredentialError
Moodle API token is required
Error message
Moodle API token is required
What it means
A ConnectorMissingCredentialError raised in MoodleConnector.load_credentials when the credentials dict has no moodle_token key (or it is falsy). The token is the sole auth mechanism for Moodle's web service API, so the connector refuses to construct its MoodleClient without it.
Solutions
- Generate a token in Moodle (Site administration > Plugins > Web services > Manage tokens) and pass it as credentials['moodle_token'].
- Verify the dict actually contains a non-empty string under exactly 'moodle_token' before calling load_credentials.
- If sourced from env/secrets, confirm the secret is mounted and the name matches.
Example fix
# before
connector.load_credentials({}) # raises ConnectorMissingCredentialError('Moodle API token is required')
# after
connector.load_credentials({'moodle_token': os.environ['MOODLE_TOKEN']}) Defensive patterns
Strategy: validation
Validate before calling
token = credentials.get("moodle_token")
if not isinstance(token, str) or not token.strip():
raise ValueError("moodle_token missing or empty") Prevention
- Validate the credentials dict shape before calling load_credentials.
- Store Moodle tokens in a secret manager and strip whitespace on read.
When it happens
Trigger: Calling load_credentials({'moodle_token': ''}) or a dict missing the key entirely — e.g. the credential payload from the UI/backend dropped the field, or an env var was empty.
Common situations: Connector credential form saved without pasting the token; env var MOODLE_TOKEN unset in the deployment; key typo (token vs moodle_token); token value of empty string after JSON round-trip.
Related errors
- Moodle token is invalid or expired
- Azure Blob: container_name is required together with…
- BigQuery: missing service_account_json
- Failed to update memory
- Jira credentials must include either an API token or…
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/e0149f50be3f47b8.
Report an issue: GitHub.
Appendix: source
Thrown at common/data_source/moodle_connector.py:73
"""Simplified logging wrapper"""
msg = f"{context}: {error}"
if level == "error":
logger.error(msg)
else:
logger.warning(msg)
def _get_latest_timestamp(self, *timestamps: int) -> int:
"""Return latest valid timestamp"""
return max((t for t in timestamps if t and t > 0), default=0)
def _yield_in_batches(self, generator: Generator[Document, None, None]) -> Generator[list[Document], None, None]:
for batch in batch_generator(generator, self.batch_size):
yield batch
def load_credentials(self, credentials: dict[str, Any]) -> None:
token = credentials.get("moodle_token")
if not token:
raise ConnectorMissingCredentialError("Moodle API token is required")
try:
self.moodle_client = MoodleClient(self.moodle_url + "/webservice/rest/server.php", token)
self.moodle_client.core.webservice.get_site_info()
except MoodleException as e:
if "invalidtoken" in str(e).lower():
raise CredentialExpiredError("Moodle token is invalid or expired")
raise ConnectorMissingCredentialError(f"Failed to initialize Moodle client: {e}")
def validate_connector_settings(self) -> None:
if not self.moodle_client:
raise ConnectorMissingCredentialError("Moodle client not initialized")
try:
site_info = self.moodle_client.core.webservice.get_site_info()
if not site_info.sitename:
raise InsufficientPermissionsError("Invalid Moodle API response")
except MoodleException as e:View on GitHub (pinned to 554fb1133a)