nocobase/nocobase · error · ResourceActionError

message not found

Error message

message not found

What it means

resendMessages needs a message to resend: if a messageId was provided it loads that message from the aiConversations.messages repository, otherwise it takes the latest message of the session. It throws this 400 ResourceActionError when no message row matches the given messageId, or (in the no-messageId branch) when the conversation has no messages at all.

Source

Thrown at packages/plugins/@nocobase/plugin-ai/src/server/resource/aiConversations.ts:614

        if (!conversation) {
          throw new ResourceActionError(400, ctx.t('conversation not found'));
        }

        const employee = await getAIEmployee(ctx, conversation.aiEmployeeUsername);
        if (!employee) {
          throw new ResourceActionError(400, ctx.t('AI employee not found'));
        }

        const resendMessages: AIMessageInput[] = [];
        if (messageId) {
          const message = await ctx.db.getRepository('aiConversations.messages', sessionId).findOne({
            filter: {
              messageId,
            },
          });

          if (!message) {
            throw new ResourceActionError(400, ctx.t('message not found'));
          }
        } else {
          const message = await ctx.db.getRepository('aiConversations.messages', sessionId).findOne({
            filter: {
              sessionId,
            },
            sort: ['-messageId'],
          });
          if (!message) {
            throw new ResourceActionError(400, ctx.t('message not found'));
          }
          messageId = message.messageId;
          if (['user', 'tool'].includes(message.role)) {
            resendMessages.push({
              role: message.role,
              content: message.content,
              toolCalls: message.toolCalls,
              attachments: message.attachments,

View on GitHub (pinned to fa42722fef)

Solutions

  1. Confirm the messageId exists in the aiConversations.messages table for that sessionId; use the server-assigned id, not a client-generated one
  2. Omit messageId to let the server pick the latest message of the conversation
  3. If the conversation is empty, send a new message via sendMessages instead of resending
  4. Ensure the message belongs to this sessionId (repository is namespaced per session)

Example fix

// before
await resource.resendMessages({ values: { sessionId, messageId: localTempId } }); // client-side id
// after
const saved = await resource('aiConversations.messages', sessionId).list();
await resource.resendMessages({ values: { sessionId, messageId: saved.data[0].messageId } });
Defensive patterns

Strategy: validation

Validate before calling

async function assertMessageResendable(sessionId, messageId) {
  const repo = resource('aiConversations.messages', sessionId);
  const res = await repo.list({ filter: messageId ? { messageId } : { sessionId }, sort: ['-messageId'], page: 1, pageSize: 1 });
  if (!res?.data?.length) throw new Error('No message available to resend in this conversation');
  return res.data[0].messageId;
}
const safeMessageId = await assertMessageResendable(sessionId, messageId);

Type guard

function isStoredMessage(msg) {
  return typeof msg === 'object' && msg !== null && typeof msg.messageId === 'string' && typeof msg.role === 'string';
}

Try / catch

try {
  await resource.resendMessages({ values: { sessionId, messageId } });
} catch (err) {
  if (err?.status === 400 && /message not found/.test(err.message ?? '')) {
    return resource.resendMessages({ values: { sessionId } }); // let server pick latest
  }
  throw err;
}

Prevention

When it happens

Trigger: resendMessages called with values.messageId that was never persisted (client-generated id, message from a different session, or already deleted); or without messageId on a conversation whose message list is empty; message written to the wrong session bucket so the filter { messageId } misses.

Common situations: Client keeps a messageId after the message was deleted server-side; passing the local optimistic-UI id instead of the server-assigned messageId; calling resend on a brand-new conversation with zero messages; running against a reset database where old message ids no longer exist.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01). Data as JSON: /api/errors/b6a56c6c3bae4c5a. Report an issue: GitHub.