influxdata/influxdb · error · anyhow::Error
Python function call failed
Error message
Python function call failed: {e} What it means
This error wraps any Python exception raised while invoking the user's processing-request plugin function (loaded via load_plugin_function) during an HTTP request trigger execution in InfluxDB 3. The Rust host calls the Python function with (local_api, query_params, request_headers, request_body, args); if that call raises any Python-side exception (traceback included in the message), it is converted into this anyhow error. It is a pass-through wrapper: the real cause is the Python traceback inside `{e}`.
Solutions
- Read the Python traceback embedded after 'Python function call failed:' in the log and fix the raised exception in the plugin code
- Verify the plugin function signature matches (api, query_params, request_headers, request_body, args)
- Wrap risky plugin sections in try/except and return an error HTTP response instead of raising
- Test the plugin's SQL queries and line protocol writes directly (influxdb3 query / write CLI) to confirm they are valid
- Ensure any third-party Python packages the plugin imports are installed in the plugin environment
Example fix
// before (plugin)
def process_request(api, query_params, headers, body, args):
table = args['table']
result = api.query(f'SELECT * FROM {table}')
// after (plugin)
def process_request(api, query_params, headers, body, args):
table = args.get('table')
if table is None:
return (400, {'error': 'missing table arg'}, {'Content-Type': 'application/json'})
result = api.query(f'SELECT * FROM "{table}"') Defensive patterns
Strategy: try-catch
Validate before calling
def _validate_args(args):
required = {'table'}
missing = required - set(args or {})
if missing:
raise ValueError(f'missing args: {missing}') Try / catch
def process_request(api, query_params, headers, body, args):
try:
# plugin logic that may raise
result = api.query('SELECT * FROM measurements')
return result
except Exception as e:
return (500, {'error': str(e)}, {'Content-Type': 'application/json'}) Prevention
- Wrap plugin bodies in try/except and return error responses instead of raising
- Test plugin SQL and line protocol against the real database before deploying
- Keep the plugin function signature (api, query_params, request_headers, request_body, args)
- Pre-install and pin all Python dependencies the plugin imports
When it happens
Trigger: The Python request-trigger function raises an exception at runtime: unhandled Python errors in plugin code (AttributeError, KeyError, etc.), the plugin calling api.query/write incorrectly (e.g. bad SQL passed to the query endpoint), exceptions raised by importable module loading at call time, or the plugin accessing api members in unsupported ways that raise Python exceptions.
Common situations: Plugin code has a bug (typo, missing import, bad index); the plugin queries a database/table that does not exist so the query call raises; the plugin writes invalid line protocol and the write endpoint errors as a Python exception; plugin expects a different argument signature than (api, query_params, request_headers, body, args); Python dependencies used by the plugin are missing in the execution environment.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Cannot write
- expected a dictionary in header item
- internal writes are not supported by the write accumulator
- Python function call failed
- Unsupported return type from Python function
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/fdaf619e081143f6.
Report an issue: GitHub.
Appendix: source
Thrown at influxdb3_py_api/src/system_py.rs:592
let query_params = map_to_py_object(py, &query_params).map_err(anyhow::Error::from)?;
let request_params = map_to_py_object(py, &request_headers).map_err(anyhow::Error::from)?;
let py_func = load_plugin_function(
py,
code,
plugin_root,
PROCESS_REQUEST_CALL_SITE,
ExecutePluginError::MissingProcessRequestFunction,
)?;
// convert the body bytes into python bytes blob
let request_body = PyBytes::new(py, &request_body[..]);
// get the result from calling the python function
let result = py_func
.call1((local_api, query_params, request_params, request_body, args))
.map_err(|e| anyhow!("Python function call failed: {}", e))?;
// Process the result according to Flask conventions
process_flask_response(py, result)
})?;
logger.log(
LogLevel::Info,
format!(
"finished execution in {}",
format_duration(start_time.elapsed())
),
);
let plugin_state = PluginReturnState {
log_lines: logger.take_log_lines(),
write_db_lines: write_accumulator.flush(),
};
View on GitHub (pinned to 06200ef96b)