ComposioHQ/composio · error · ValidationError
A non-empty userId is required to create a trigger
Error message
A non-empty userId is required to create a trigger
What it means
ValidationError('A non-empty userId is required to create a trigger') is thrown by Triggers.create when userId is undefined, null, or whitespace-only (checked via !userId?.trim()). Trigger instances are scoped per user, so this guard fires first — before body schema validation and any network call. Note it carries no cause.
Source
Thrown at ts/packages/core/src/models/Triggers.ts:332
}
/**
* Create a new trigger instance for a user
* If the connected account id is not provided, the first connected account for the user and toolkit will be used
*
* @param {string} userId - The user id of the trigger instance
* @param {string} slug - The slug of the trigger instance
* @param {TriggerInstanceUpsertParams} body - The parameters to create the trigger instance
* @returns {Promise<TriggerInstanceUpsertResponse>} The created trigger instance
*/
async create(
userId: string,
slug: string,
body?: TriggerInstanceUpsertParams,
requestOptions?: ComposioRequestOptions
): Promise<TriggerInstanceUpsertResponse> {
if (!userId?.trim()) {
throw new ValidationError(`A non-empty userId is required to create a trigger`);
}
const parsedBody = TriggerInstanceUpsertParamsSchema.safeParse(body ?? {});
if (!parsedBody.success) {
throw new ValidationError(`Invalid parameters passed to create trigger`, {
cause: parsedBody.error,
});
}
// Validate the trigger slug up-front so callers get a clear client-side
// `ComposioTriggerTypeNotFoundError`. The Python SDK mirrors this behavior.
try {
await this.getType(slug, requestOptions);
} catch (error) {
// The trigger types endpoint returns 400 (not 404) for an unknown slug.
if (error instanceof APIError && (error.status === 400 || error.status === 404)) {
throw new ComposioTriggerTypeNotFoundError(`Trigger type ${slug} not found`, {View on GitHub (pinned to 64b1b85502)
Solutions
- Pass a real non-empty user identifier as the first argument
- Verify argument order: create(userId, slug, body)
- Assert a non-empty user id upstream (e.g. from the auth session) before creating triggers
Example fix
// before
await triggers.create('', 'github_issue_opened', { triggerConfig: {...} });
// after
await triggers.create('user_12345', 'github_issue_opened', { triggerConfig: {...} }); Defensive patterns
Strategy: type-guard
Validate before calling
const userId = session.user?.id ?? '';
if (!userId.trim()) throw new Error('Cannot create trigger: no authenticated user');
await triggers.create(userId, slug, body); Type guard
const isNonEmptyUserId = (id: unknown): id is string => typeof id === 'string' && id.trim().length > 0;
Try / catch
try {
await triggers.create(userId, slug, body);
} catch (e) {
if (e instanceof ValidationError && /non-empty userId/.test(e.message)) {
// re-authenticate or skip trigger creation for anonymous users
}
} Prevention
- Assert a non-empty user id before per-user trigger creation
- Check argument order: (userId, slug, body)
- Type the call so an undefined userId fails at compile time
When it happens
Trigger: Calling triggers.create(userId, slug, body) with userId that is undefined, '', or ' '.
Common situations: Wrong argument order (passing slug first); userId loaded from an unset session/env variable; refactors renaming the user-id variable leaving undefined; background jobs where the user context was lost.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Invalid parameters passed to set webhook subscription
- Invalid parameters passed to list triggers
- Invalid parameters passed to create trigger
- Invalid tool execute parameters
- Invalid tool execute session parameters
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/9f6292db70f5d7ac.
Report an issue: GitHub.