infiniflow/ragflow · error · ConnectorValidationError

Unexpected validation error: {e}

Error message

Unexpected validation error: {e}

What it means

A ConnectorValidationError raised in validate_connector_settings as the final except branch: get_site_info() threw something other than a MoodleException (connection error, timeout, SSL failure, JSON decode error), and the raw exception is embedded into the message. It is the catch-all for infrastructure-level failures during validation.

Source

Thrown at common/data_source/moodle_connector.py:99

            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:
            raise ConnectorValidationError(f"Unexpected validation error: {e}")

    # -------------------------------------------------------------------------
    # Data loading & polling
    # -------------------------------------------------------------------------

    def load_from_state(self) -> Generator[list[Document], None, None]:
        if not self.moodle_client:
            raise ConnectorMissingCredentialError("Moodle client not initialized")

        logger.info("Starting full load from Moodle workspace")
        courses = self._get_enrolled_courses()
        if not courses:
            logger.warning("No courses found to process")
            return

        yield from self._yield_in_batches(self._process_courses(courses))

    def poll_source(self, start: SecondsSinceUnixEpoch, end: SecondsSinceUnixEpoch) -> Generator[list[Document], None, None]:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Read the embedded exception text — it distinguishes DNS ('Name or service not known'), TLS ('certificate verify failed'), timeout, and parse errors.
  2. For TLS issues, import the internal CA into the indexer's trust store (avoid disabling verification in production).
  3. For timeouts, check Moodle health/latency and raise the client's timeout if the site is slow.
  4. Verify network egress from the connector host to <moodle_url>/webservice/rest/server.php with curl.

Example fix

# before
connector.validate_connector_settings()  # ConnectorValidationError('Unexpected validation error: <urlopen error ...>')

# after
# fix reachability / trust first, then surface specifics
try:
    connector.validate_connector_settings()
except ConnectorValidationError as exc:
    logging.error("Moodle validation failed: %s", exc)
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

import socket, ssl, requests

def moodle_endpoint_reachable(moodle_url: str) -> bool:
    try:
        requests.get(moodle_url, timeout=10)
        return True
    except (requests.ConnectionError, requests.Timeout, ssl.SSLError, socket.gaierror):
        return False

Try / catch

try:
    connector.validate_connector_settings()
except ConnectorValidationError as exc:
    msg = str(exc)
    if 'certificate verify failed' in msg:
        install_internal_ca()
    elif 'timed out' in msg or 'Connection' in msg:
        check_egress_and_moodle_health()
    else:
        raise

Prevention

When it happens

Trigger: Any non-Moodle exception from the client during get_site_info — DNS failure for moodle_url, connection refused, TLS certificate verification error, socket timeout, or a 200 response with a non-JSON body that breaks parsing.

Common situations: Wrong/unreachable moodle_url; self-signed cert without proper trust; firewall blocking egress from the indexer; Moodle fronted by a proxy returning HTML; slow site hitting the HTTP client timeout.

Related errors


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