tinyhumansai/openhuman · error · anyhow::Error

flow_id must not be empty

Error message

flow_id must not be empty

What it means

The `approval_preauthorize_flow` RPC was called with an empty `flow_id` string. Pre-authorization keys blanket tool grants to a specific flow, so an empty id has nothing to attach grants to; the guard rejects it before any idempotent INSERT runs. Note this is about the id being empty, not the flow being unknown.

Source

Thrown at src/openhuman/security/approval/rpc.rs:117

/// (consolidated pre-authorization card). Loops the idempotent
/// `INSERT OR IGNORE` per tool and writes one born-decided audit row per
/// *new* grant so blanket approvals stay visible in Approval history.
///
/// Unlike `approval_decide`, a missing gate is NOT an error: with the gate
/// uninstalled (`OPENHUMAN_APPROVAL_GATE=0`) nothing ever parks, so there is
/// nothing to pre-authorize — the call reports `gate_installed: false` and
/// succeeds, keeping the save-and-enable UX identical in both modes.
pub async fn approval_preauthorize_flow(
    flow_id: &str,
    tool_names: Vec<String>,
) -> anyhow::Result<RpcOutcome<FlowPreauthorizationResult>> {
    tracing::debug!(
        flow_id = flow_id,
        tools = tool_names.len(),
        "[rpc:approval_preauthorize_flow] entry"
    );
    if flow_id.trim().is_empty() {
        return Err(anyhow!("flow_id must not be empty"));
    }
    if tool_names.len() > MAX_PREAUTHORIZE_TOOLS {
        return Err(anyhow!(
            "too many tool_names ({}); max {MAX_PREAUTHORIZE_TOOLS}",
            tool_names.len()
        ));
    }
    let Some(gate) = ApprovalGate::try_global() else {
        tracing::info!(
            flow_id = flow_id,
            "[rpc:approval_preauthorize_flow] gate not installed; nothing to grant"
        );
        return Ok(RpcOutcome::single_log(
            FlowPreauthorizationResult {
                flow_id: flow_id.to_string(),
                granted: vec![],
                already_trusted: vec![],
                gate_installed: false,

View on GitHub (pinned to 7491200858)

Solutions

  1. Pass the real flow id from the saved flow
  2. Trim whitespace before sending
  3. Ensure the flow was saved (has an id) before pre-authorizing it
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/openhuman/security/approval/rpc.rs:117 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/c0d24f893a285938. Report an issue: GitHub.