tinyhumansai/openhuman · error · anyhow::Error
composio.create_trigger: slug must not be empty
Error message
composio.create_trigger: slug must not be empty
What it means
ComposioClient::create_trigger rejects a trigger slug that is empty after trimming, before POST /agent-integrations/composio/triggers is built. The slug identifies the trigger type; blank input is a caller bug the client refuses to forward.
Source
Thrown at src/openhuman/integrations/composio/client.rs:362
let path = match connection_id.map(str::trim).filter(|id| !id.is_empty()) {
Some(id) => format!("/agent-integrations/composio/github/repos?connectionId={id}"),
None => "/agent-integrations/composio/github/repos".to_string(),
};
tracing::debug!(path = %path, "[composio] list_github_repos");
self.inner.get::<ComposioGithubReposResponse>(&path).await
}
/// `POST /agent-integrations/composio/triggers` — create a trigger
/// instance for the authenticated user.
pub async fn create_trigger(
&self,
slug: &str,
connection_id: Option<&str>,
trigger_config: Option<serde_json::Value>,
) -> Result<ComposioCreateTriggerResponse> {
let slug = slug.trim();
if slug.is_empty() {
anyhow::bail!("composio.create_trigger: slug must not be empty");
}
let mut body = json!({ "slug": slug });
if let Some(connection_id) = connection_id.map(str::trim).filter(|id| !id.is_empty()) {
body["connectionId"] = json!(connection_id);
}
if let Some(config) = trigger_config {
body["triggerConfig"] = config;
}
tracing::debug!(slug = %slug, "[composio] create_trigger");
self.inner
.post::<ComposioCreateTriggerResponse>("/agent-integrations/composio/triggers", &body)
.await
}
// ── Trigger management (PR #671) ────────────────────────────────
/// `GET /agent-integrations/composio/triggers/available` — catalog of
/// triggers the user could enable for a toolkit. For GitHub theView on GitHub (pinned to 7491200858)
Solutions
- Require trigger template selection before the create action is enabled
- Validate slug non-empty (and ideally against list_available_triggers output) at the RPC/config boundary
- Log the originating flow/automation when this fires to find which producer omits the slug
Example fix
// before
client.create_trigger(&node.slug, conn_id, cfg).await?;
// after
let slug = node.slug.trim();
if slug.is_empty() {
anyhow::bail!("trigger node {} has no slug; fix the automation definition", node.id);
}
client.create_trigger(slug, conn_id, cfg).await?; Defensive patterns
Strategy: validation
Validate before calling
let slug = slug.trim();
if slug.is_empty() {
anyhow::bail!("trigger slug is required to create a trigger");
}
client.create_trigger(slug, connection_id, trigger_config).await?; Type guard
fn is_non_empty_slug(s: &str) -> bool {
!s.trim().is_empty()
} Prevention
- Require trigger-template selection before create is reachable in the flow
- Validate automation/flow definitions at load time: every trigger node must carry a slug
- Validate slugs against the available-triggers catalog to reject unknown values early
When it happens
Trigger: Calling create_trigger("", connection_id, trigger_config) or with a whitespace-only slug — usually a UI flow where the trigger template was not yet selected, or an automation config whose trigger key is missing.
Common situations: Trigger-creation form submitted with no template chosen; trigger slug read from a renamed config key; flows/automations engine instantiating a trigger from an incompletely-defined node.
Related errors
- composio.list_available_triggers: toolkit must not be empty
- composio.enable_trigger: connectionId must not be empty
- composio.enable_trigger: slug must not be empty
- composio.disable_trigger: triggerId must not be empty
- composio.execute_tool: tool slug must not be empty
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/38e14542d36ccc22.
Report an issue: GitHub.