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.
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)
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
- main() must be defined or exported.
- Failed to update memory
- Azure Blob: container_name is required together with account
- BigQuery: missing service_account_json
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/e0149f50be3f47b8.
Report an issue: GitHub.