toeverything/AFFiNE · error · CopilotFailedToCreateMessage
copilot_failed_to_create_message
copilot_failed_to_create_message
Error message
e.message
What it means
createCopilotMessage wraps ANY failure of inbox.createMessage into CopilotFailedToCreateMessage (code `copilot_failed_to_create_message`, status `internal_server_error`), forwarding the original e.message. It is a wrapper error: the actionable cause is the message text carried inside, which comes from the inbox pipeline (session lookup, params validation, attachments, downstream providers).
Source
Thrown at packages/backend/server/src/plugins/copilot/resolver.ts:781
@Mutation(() => String, {
description: 'Create a chat message',
})
@CallMetric('ai', 'chat_message_create')
async createCopilotMessage(
@CurrentUser() user: CurrentUser,
@Args({ name: 'options', type: () => CreateChatMessageInput })
options: CreateChatMessageInput
): Promise<string> {
const lockFlag = `${COPILOT_LOCKER}:message:${user?.id}:${options.sessionId}`;
await using lock = await this.mutex.acquire(lockFlag);
if (!lock) {
throw new TooManyRequest('Server is busy');
}
try {
return await this.inbox.createMessage(user.id, options);
} catch (e: any) {
throw new CopilotFailedToCreateMessage(e.message);
}
}
private transformToSessionType(session: Omit<ChatHistory, 'messages'>) {
return { id: session.sessionId, ...session };
}
}
@Throttle()
@CopilotEnabled()
@Resolver(() => UserType)
export class UserCopilotResolver {
constructor(private readonly ac: PermissionAccess) {}
@ResolveField(() => CopilotType)
async copilot(
@CurrentUser() user: CurrentUser,
@Args('workspaceId', { nullable: true }) workspaceId?: stringView on GitHub (pinned to b4c8548c09)
Solutions
- Read the forwarded message — it names the underlying cause thrown by inbox.createMessage
- Verify the sessionId still exists (query copilot session history) before sending
- Check the attachment/params payload for size, format, and required fields
- Correlate with server logs for the original stack of the wrapped error (the wrapper hides trace location)
Example fix
// before
try {
await createCopilotMessage({ variables: { options } });
} catch (e) {
toast('Failed'); // underlying cause lost
}
// after
try {
await createCopilotMessage({ variables: { options } });
} catch (e) {
const cause = (e as GraphQLError)?.extensions?.code === 'copilot_failed_to_create_message'
? (e as Error).message // server forwarded inbox error text
: 'Failed to send';
toast(cause);
} Defensive patterns
Strategy: try-catch
Validate before calling
// guard: verify the session exists and the payload is sane before sending
const sessions = await fetchCopilotSessions(workspaceId);
if (!sessions.some(s => s.id === options.sessionId)) {
throw new Error('session missing — recreate before sending');
}
if (options.attachments?.some(a => a.size > MAX_ATTACHMENT_BYTES)) {
throw new Error('attachment too large');
} Type guard
function isFailedToCreateMessage(e: unknown): boolean {
return (e as { extensions?: { code?: string } })?.extensions?.code === 'copilot_failed_to_create_message';
} Try / catch
try {
return await createCopilotMessage({ variables: { options } });
} catch (e) {
if (isFailedToCreateMessage(e)) {
// e.message carries the forwarded inbox error — surface it, do not blind-retry
reportToUser((e as Error).message);
return null;
}
throw e;
} Prevention
- Check the session exists before sending if it may have been cleaned up
- Validate attachment size/format client-side before the mutation
- Always log the forwarded inner message — the wrapper alone says nothing actionable
When it happens
Trigger: inbox.createMessage throws: the sessionId no longer exists, message params/attachments fail validation, the workspace's AI provider or DB rejects the request, or a downstream prompt/runtime error occurred while enqueueing the message.
Common situations: Sending into a session deleted by cleanup; oversized or malformed attachments; provider credentials/quota issues surfacing at message-create time; custom inbox code paths that throw plain Errors.
Related errors
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/ef5a619e99d0f923.
Report an issue: GitHub.