Dokploy/dokploy · error · TRPCError
FORBIDDEN
FORBIDDEN
Error message
Access denied
What it means
Guard inside updateSlackNotification: the UPDATE on the notifications row for input.notificationId returned no row — meaning no notification with that ID exists (or it was deleted), so the update is rejected and the subsequent slack-table update never runs.
Source
Thrown at apps/dokploy/server/api/routers/ai.ts:247
.input(
z.object({
aiId: z.string().min(1),
logs: z.string().min(1),
context: z.enum(["build", "runtime"]),
}),
)
.mutation(async ({ input, ctx }) => {
try {
const aiSettings = await getAiSettingById(input.aiId);
if (!aiSettings?.isEnabled) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "AI provider is not enabled",
});
}
if (aiSettings.organizationId !== ctx.session.activeOrganizationId) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Access denied",
});
}
const provider = selectAIProvider(aiSettings);
const model = provider(aiSettings.model);
const contextLabel =
input.context === "build" ? "build/deployment" : "runtime/container";
const result = await generateText({
model,
prompt: `You are a DevOps engineer analyzing ${contextLabel} logs. Analyze the following logs and provide:
1. **Summary**: A brief summary of what's happening
2. **Issues Found**: Any errors, warnings, or problems detected
3. **Root Cause**: The most likely root cause if there are errorsView on GitHub (pinned to 546686ea35)
Solutions
- Refetch the notification list and confirm the ID still exists before editing
- Handle BAD_REQUEST here as 'stale ID' and prompt the user to reload
- Verify you are passing notificationId (not the slack row ID) — they are different identifiers
Defensive patterns
Strategy: validation
Validate before calling
const dest = await db.query.notifications.findFirst({
where: eq(notifications.notificationId, input.notificationId),
});
if (!dest) throw new Error('Notification no longer exists'); Try / catch
try { await updateSlackNotification(input); } catch (e) { if (e?.message?.includes('Error Updating')) { /* refetch list and retry */ } throw e; } Prevention
- Refetch notifications before editing
- Always send notificationId, never the slack row ID
When it happens
Trigger: Calling updateSlackNotification with a stale, deleted, or mistyped notificationId; concurrent deletion of the destination; updating a notification that belongs to a different resource scope.
Common situations: Client caching an old notification list; two admins editing where one deletes; ID copy/paste errors.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No response received from the model
- UNAUTHORIZED
- Failed to fetch models: ${errorText}
- INTERNAL_SERVER_ERROR
- INTERNAL_SERVER_ERROR
AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27).
Data as JSON: /api/errors/cad815574c312bac.
Report an issue: GitHub.