infiniflow/ragflow · error · InsufficientPermissionsError
Invalid Moodle API response
Error message
Invalid Moodle API response
What it means
An InsufficientPermissionsError raised in validate_connector_settings when the get_site_info() call succeeds but the response has an empty sitename. The connector treats a site-info response without a sitename as structurally invalid — a well-formed Moodle answer always includes sitename, so its absence signals a gateway/SSO interception or a broken web-service response rather than a permission scope issue per se.
Source
Thrown at common/data_source/moodle_connector.py:90
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:
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")
View on GitHub (pinned to 554fb1133a)
Solutions
- Verify moodle_url is the Moodle root (e.g. https://moodle.org) and that /webservice/rest/server.php is reachable.
- Call the web service manually: curl '<moodle_url>/webservice/rest/server.php?wstoken=TOKEN&wsfunction=core_webservice_get_site_info&moodlewsrestformat=json' and inspect the JSON for sitename.
- If the raw response lacks sitename, fix the Moodle web-services configuration or the proxy in front of it.
Example fix
# before
connector = MoodleConnector(moodle_url='https://org.example/sso') # proxy answers, sitename empty
connector.load_credentials(creds)
connector.validate_connector_settings() # InsufficientPermissionsError('Invalid Moodle API response')
# after
connector = MoodleConnector(moodle_url='https://moodle.org') # real Moodle root
connector.load_credentials(creds)
connector.validate_connector_settings() Defensive patterns
Strategy: validation
Validate before calling
import requests
def moodle_site_info_ok(moodle_url: str, token: str) -> bool:
r = requests.get(
f"{moodle_url}/webservice/rest/server.php",
params={"wstoken": token, "wsfunction": "core_webservice_get_site_info", "moodlewsrestformat": "json"},
timeout=10,
)
data = r.json()
return bool(data.get("sitename")) Try / catch
try:
connector.validate_connector_settings()
except InsufficientPermissionsError as exc:
if "Invalid Moodle API response" in str(exc):
check_proxy_and_url(connector.moodle_url) # structural response problem
else:
fix_web_service_permissions() Prevention
- Point moodle_url at the Moodle root; ensure no SSO/proxy rewrites webservice responses.
- Pre-flight get_site_info with plain HTTP and assert sitename is non-empty.
When it happens
Trigger: get_site_info() returns 200 with an object whose sitename is empty/None — e.g. a proxy returning an empty shell response, a non-Moodle endpoint answering at moodle_url, or a Moodle plugin/version returning a degenerate payload.
Common situations: moodle_url pointing at the wrong path or a reverse proxy login page that happens to parse; Moodle version with web services partially disabled returning an empty info object; SAML/SSO fronting that rewrites responses.
Related errors
- Insufficient permissions. Ensure web services are enabled an
- main() must return a value. Use null for an empty result.
- main() returned a non-JSON-serializable value.
- message.compileNotSupported
- Failed to fetch search detail
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/65469bdc980254be.
Report an issue: GitHub.