influxdata/influxdb · error · ExecutePluginError
Failed to import plugin module '{}': {} Hint: Check for synt
Error message
Failed to import plugin module '{}': {}
Hint: Check for syntax errors or missing dependencies in Python files. What it means
For multi-file plugins, load_function_from_module temporarily inserts the plugin directory into sys.path (under a lock) and imports the module. Any import failure — syntax error, missing dependency, bad package layout — is wrapped as ExecutePluginError::PluginError with the module name and the original Python exception text, plus the hint about syntax errors and missing dependencies. The original traceback text in '{}' is the real cause and must be read first.
Source
Thrown at influxdb3_py_api/src/system_py.rs:373
// A plugin dir added after FileFinder cached the parent is invisible until
// import caches are invalidated; retry once.
let import_result = match py.import(module_name) {
Err(e) if is_module_not_found(py, &e, module_name) => {
let _ = py
.import("importlib")
.and_then(|m| m.call_method0("invalidate_caches"));
py.import(module_name)
}
result => result,
};
// Always cleanup sys.path, even if import failed. The getattr lookup below
// operates on the imported module object and no longer needs sys.path.
let _ = sys_path.call_method1("pop", (0,));
// Any import failure is the real load error and must not be masked.
let module = import_result.map_err(|e| {
ExecutePluginError::PluginError(anyhow!(
"Failed to import plugin module '{}': {}\n\
Hint: Check for syntax errors or missing dependencies in Python files.",
module_name,
e
))
})?;
module.getattr(function_name).map_err(|e| {
// Only a missing attribute on the imported module means the entry-point
// function is absent; surface anything else as the real cause.
if e.is_instance_of::<PyAttributeError>(py) {
missing_fn_error
} else {
ExecutePluginError::PluginError(anyhow!(
"Failed to load function '{}' from plugin module '{}': {}",
function_name,
module_name,
eView on GitHub (pinned to d28e26e048)
Solutions
- Read the exception text after the module name — it names the missing module or the exact syntax error
- Byte-compile all plugin files before deploying: python -m py_compile plugin/__init__.py plugin/*.py
- Install missing dependencies into the server's plugin Python environment, or vendor them as files inside the plugin directory
- Confirm the plugin directory layout: __init__.py present, entry-point function defined, and syntax compatible with the server's Python version
Example fix
# before: __init__.py imports a package the server env lacks import requests # ModuleNotFoundError -> Failed to import plugin module # after: vendor the dependency beside the plugin or use the stdlib from plugin.vendor.requests import Session # vendored copy shipped in the plugin dir
Defensive patterns
Strategy: try-catch
Validate before calling
# deploy-time check: byte-compile every plugin file before upload
python -m py_compile plugin/__init__.py plugin/*.py \
|| { echo "plugin has syntax errors — fix before deploy" >&2; exit 1; } Try / catch
match execute_plugin(/* ... */).await {
Err(ExecutePluginError::PluginError(e))
if e.to_string().contains("Failed to import plugin module") =>
{
// surface the embedded Python error + hint to the plugin author verbatim
Err(PluginLoadRejected(e))
}
other => other,
} Prevention
- Compile all plugin files (py_compile) in CI before deployment
- Pin and document the plugin's dependencies; vendor them inside the plugin dir if the server env is fixed
- Match the server's Python version — avoid syntax newer than its interpreter
- Read the original exception after the module name in the message; it names the missing module or exact syntax error
When it happens
Trigger: A plugin whose __init__.py or sibling module has a syntax error; imports a third-party package absent from the server's Python environment; has no/corrupt __init__.py layout; or uses Python syntax newer than the interpreter embedded in the server.
Common situations: Plugin developed in a personal venv then deployed to the server runtime that lacks those packages; partial uploads (a module referenced but not shipped); Python version mismatch (e.g. match statements on an older interpreter); circular imports between plugin modules.
Related errors
- plugin code contains null bytes
- Measurement name cannot contain spaces
- {key_type} key cannot be empty
- {key_type} key '{key}' cannot contain spaces
- {key_type} key '{key}' cannot contain commas
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/387b65a31a1972e4.
Report an issue: GitHub.