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

  1. Read the Python traceback embedded after 'Python function call failed:' in the log and fix the raised exception in the plugin code
  2. Verify the plugin function signature matches (api, query_params, request_headers, request_body, args)
  3. Wrap risky plugin sections in try/except and return an error HTTP response instead of raising
  4. Test the plugin's SQL queries and line protocol writes directly (influxdb3 query / write CLI) to confirm they are valid
  5. 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

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


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)