{"record":{"id":"c0d24f893a285938","repo":"tinyhumansai/openhuman","slug":"flow-id-must-not-be-empty","errorCode":null,"errorMessage":"flow_id must not be empty","messagePattern":"flow_id must not be empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/openhuman/security/approval/rpc.rs","lineNumber":117,"sourceCode":"/// (consolidated pre-authorization card). Loops the idempotent\n/// `INSERT OR IGNORE` per tool and writes one born-decided audit row per\n/// *new* grant so blanket approvals stay visible in Approval history.\n///\n/// Unlike `approval_decide`, a missing gate is NOT an error: with the gate\n/// uninstalled (`OPENHUMAN_APPROVAL_GATE=0`) nothing ever parks, so there is\n/// nothing to pre-authorize — the call reports `gate_installed: false` and\n/// succeeds, keeping the save-and-enable UX identical in both modes.\npub async fn approval_preauthorize_flow(\n    flow_id: &str,\n    tool_names: Vec<String>,\n) -> anyhow::Result<RpcOutcome<FlowPreauthorizationResult>> {\n    tracing::debug!(\n        flow_id = flow_id,\n        tools = tool_names.len(),\n        \"[rpc:approval_preauthorize_flow] entry\"\n    );\n    if flow_id.trim().is_empty() {\n        return Err(anyhow!(\"flow_id must not be empty\"));\n    }\n    if tool_names.len() > MAX_PREAUTHORIZE_TOOLS {\n        return Err(anyhow!(\n            \"too many tool_names ({}); max {MAX_PREAUTHORIZE_TOOLS}\",\n            tool_names.len()\n        ));\n    }\n    let Some(gate) = ApprovalGate::try_global() else {\n        tracing::info!(\n            flow_id = flow_id,\n            \"[rpc:approval_preauthorize_flow] gate not installed; nothing to grant\"\n        );\n        return Ok(RpcOutcome::single_log(\n            FlowPreauthorizationResult {\n                flow_id: flow_id.to_string(),\n                granted: vec![],\n                already_trusted: vec![],\n                gate_installed: false,","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/security/approval/rpc.rs#L99-L135","documentation":"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.","triggerScenarios":"Thrown at src/openhuman/security/approval/rpc.rs:117 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass the real flow id from the saved flow","Trim whitespace before sending","Ensure the flow was saved (has an id) before pre-authorizing it"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}