infiniflow/ragflow · error · CredentialExpiredError
Moodle token is invalid or expired
Error message
Moodle token is invalid or expired
What it means
A CredentialExpiredError raised in load_credentials when constructing the MoodleClient and calling core.webservice.get_site_info() throws a MoodleException whose text contains 'invalidtoken'. The probe call doubles as credential verification; Moodle returns an invalidtoken error code when the token does not exist, was revoked, or expired.
Source
Thrown at common/data_source/moodle_connector.py:80
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:
msg = str(e).lower()
if "invalidtoken" in msg:
raise CredentialExpiredError("Moodle token is invalid or expired")
if "accessexception" in msg:
raise InsufficientPermissionsError("Insufficient permissions. Ensure web services are enabled and permissions are correct.")
raise ConnectorValidationError(f"Moodle validation error: {e}")
except Exception as e:View on GitHub (pinned to 554fb1133a)
Solutions
- Issue a fresh token in Moodle (Manage tokens) and update the stored credential.
- Confirm the token belongs to the same Moodle site as moodle_url.
- Strip whitespace from the token before storing it.
- If tokens keep expiring, ask the Moodle admin to set a longer TTL or create a system-token for the service.
Example fix
# before
connector.load_credentials({'moodle_token': old_token}) # CredentialExpiredError: Moodle token is invalid or expired
# after
token = os.environ['MOODLE_TOKEN'].strip()
connector.load_credentials({'moodle_token': token}) Defensive patterns
Strategy: retry
Try / catch
try:
connector.load_credentials({'moodle_token': token})
except CredentialExpiredError:
token = request_new_moodle_token() # admin/API re-issue
connector.load_credentials({'moodle_token': token}) Prevention
- Automate token rotation instead of hard-coding one token forever.
- Strip whitespace and confirm the token belongs to the target site before first use.
When it happens
Trigger: Calling load_credentials with a token that Moodle rejects during the get_site_info handshake — deleted/expired token, token for a different site, or a token whose user was removed.
Common situations: Token TTL elapsed (Moodle tokens can be configured to expire); admin pruned tokens; token copied from another Moodle instance; trailing whitespace/newline pasted with the token.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Moodle API token is required
- main() must be defined or exported.
- Jira credentials must include either an API token or usernam
- Moodle client not initialized
- Invalid chat_id: ${payload.chat_id}
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/7eeef52d2578e075.
Report an issue: GitHub.