tinyhumansai/openhuman · error
integration id is required
Error message
integration id is required
What it means
Thrown by revoke_integration when the integration id is empty after trimming. The revoke is a DELETE on auth/integrations/{id}; unlike the handoff/client-key methods there is no 24-char length requirement here — only non-emptiness — but the id is still the backend integration identifier. Input validation only.
Source
Thrown at src/api/rest.rs:1121
) -> Result<Value> {
let channel = channel.trim().trim_matches('/');
anyhow::ensure!(!channel.is_empty(), "channel is required");
let encoded = urlencoding::encode(channel);
let mut path = format!("channels/{encoded}/threads");
if let Some(active) = active_filter {
path.push_str(if active {
"?active=true"
} else {
"?active=false"
});
}
self.authed_json(bearer_jwt, Method::GET, &path, None).await
}
/// Revokes (deletes) an active integration.
pub async fn revoke_integration(&self, integration_id: &str, bearer_jwt: &str) -> Result<()> {
let id = integration_id.trim();
anyhow::ensure!(!id.is_empty(), "integration id is required");
self.authed_json(
bearer_jwt,
Method::DELETE,
&format!("auth/integrations/{id}"),
None,
)
.await?;
Ok(())
}
}
/// AES-256-GCM decrypt compatible with backend `encryptMessageFromString` (IV 16 + tag 16 + ciphertext, base64).
pub fn decrypt_handoff_blob(b64_ciphertext: &str, key_str: &str) -> Result<String> {
let key = key_bytes_from_string(key_str)?;
let combined = base64::engine::general_purpose::STANDARD
.decode(b64_ciphertext.trim())
.context("base64-decode encrypted payload")?;
if combined.len() < 32 {View on GitHub (pinned to a221052e0d)
Solutions
- Pass the id verbatim from list_integrations
- Disable revoke actions on rows without an id
- Guard at the call site with trim()
Example fix
// before client.revoke_integration(&integration_id, &jwt).await?; // integration_id = "" // after let id = integration_id.trim(); anyhow::ensure!(!id.is_empty(), "integration id is required to revoke"); client.revoke_integration(id, &jwt).await?;
Defensive patterns
Strategy: validation
Validate before calling
let id = integration_id.trim(); anyhow::ensure!(!id.is_empty(), "integration id is required to revoke"); client.revoke_integration(id, &jwt).await?;
Type guard
fn has_integration_id(s: &str) -> bool {
!s.trim().is_empty()
} Prevention
- Source the id from list_integrations rows and disable revoke actions on rows without one
- Confirm destructive actions (revoke) with the integration name, not the raw id, before calling
When it happens
Trigger: Calling revoke_integration("") — e.g. a revoke action dispatched from a UI row whose id failed to load, or a stale record with a blank id field.
Common situations: Settings screen's revoke button enabled on a row rendered from partial data, or an id lost through serialization after a refactor.
Related errors
- integrationId must be a 24-char hex id
- API base URL must be an absolute http(s) URL with host
- provider is required
- login token is required
- channel is required
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/2c623438734d494d.
Report an issue: GitHub.