calcom/cal.diy · error · BadRequestException

username is required for non-team events, please provide a v

Error message

username is required for non-team events, please provide a valid username

What it means

Thrown by EventTypesAtomService.getPublicEventTypeForAtoms when isTeamEvent is false or undefined and no username is provided. For non-team events, the username serves as the URL path component to look up the public event type. Without it, getPublicEvent cannot resolve the event owner and BadRequestException (HTTP 400) is thrown.

Source

Thrown at apps/api/v2/src/modules/atoms/services/event-types-atom.service.ts:386

    teamId,
  }: {
    username?: string;
    eventSlug: string;
    isTeamEvent?: boolean;
    orgId?: number;
    teamId?: number;
  }): Promise<PublicEventType> {
    const orgSlug = orgId ? await this.getTeamSlug(orgId) : null;

    let usernameOrTeamSlug: string | null = null;
    if (isTeamEvent) {
      if (!teamId) {
        throw new BadRequestException("teamId is required for team events, please provide a valid teamId");
      }
      usernameOrTeamSlug = await this.getTeamSlug(teamId);
    } else {
      if (!username) {
        throw new BadRequestException(
          "username is required for non-team events, please provide a valid username"
        );
      }
      usernameOrTeamSlug = username;
    }

    usernameOrTeamSlug = usernameOrTeamSlug.toLowerCase();

    try {
      let event = await getPublicEvent(
        usernameOrTeamSlug,
        eventSlug,
        isTeamEvent,
        orgSlug,
        this.dbRead.prisma as unknown as PrismaClient,
        true
      );

View on GitHub (pinned to 176037d0af)

Solutions

  1. Provide a valid username when isTeamEvent is false or not set: include it in the query or body.
  2. If the intent is a team event, set isTeamEvent: true and provide teamId instead.
  3. Ensure the username corresponds to an existing user with event types.

Example fix

// before: non-team event without username
const event = await atomsApi.getPublicEventType({
  eventSlug: '30min'
  // username missing, isTeamEvent omitted (falsy)
});

// after: include username for user events
const event = await atomsApi.getPublicEventType({
  eventSlug: '30min',
  username: 'john.doe'
});
Defensive patterns

Strategy: validation

Validate before calling

// Validate that username is present for non-team events
const validateNonTeamEventRequest = (params: {
  isTeamEvent?: boolean;
  username?: string;
}): void => {
  if (!params.isTeamEvent && !params.username) {
    throw new Error('username is required for non-team events.');
  }
};

Type guard

type NonTeamEventRequest = { eventSlug: string; username: string; isTeamEvent?: false };
const isNonTeamRequest = (p: any): p is NonTeamEventRequest =>
  p.eventSlug && typeof p.username === 'string' && (!p.isTeamEvent || p.isTeamEvent === false);

Prevention

When it happens

Trigger: Calling the public event-type atoms endpoint with { isTeamEvent: false } (or omitted) but no username. The client assumes a default user context but doesn't pass it. A request constructed from a URL where the username segment was empty.

Common situations: Anon/public booking page that lost the username context. API client that defaults to the authenticated user but doesn't translate that into a username parameter for this endpoint. Test fixture for a user event that omits username. Frontend route handler that parses the URL but finds an empty username segment.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/f870d1889c4285bc. Report an issue: GitHub.