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

  1. Generate a token in Moodle (Site administration > Plugins > Web services > Manage tokens) and pass it as credentials['moodle_token'].
  2. Verify the dict actually contains a non-empty string under exactly 'moodle_token' before calling load_credentials.
  3. 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

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


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/e0149f50be3f47b8. Report an issue: GitHub.