Kareadita/Kavita · warning · KavitaException

dashboard-stream-doesnt-exist

dashboard-stream-doesnt-exist

Error message

dashboard-stream-doesnt-exist

What it means

Thrown by StreamService.UpdateDashboardStream when UserRepository.GetDashboardStream(dto.Id) returns null — the dashboard stream id does not exist. The message is translated to 'Dashboard Stream doesn't exist'. StreamController.UpdateDashboardStream does not catch KavitaException, so it surfaces as HTTP 500 via ExceptionMiddleware. (A subsequent ownership check on an existing-but-foreign stream instead throws KavitaNotFoundException, which becomes HTTP 404.)

Source

Thrown at Kavita.Services/StreamService.cs:93

            Id = createdStream.Id,
            Name = createdStream.Name,
            IsProvided = createdStream.IsProvided,
            Visible = createdStream.Visible,
            Order = createdStream.Order,
            SmartFilterEncoded = smartFilter.Filter,
            StreamType = createdStream.StreamType
        };

        await eventHub.SendMessageToAsync(MessageFactory.DashboardUpdate, MessageFactory.DashboardUpdateEvent(user.Id),
            userId, ct);

        return ret;
    }

    public async Task UpdateDashboardStream(int userId, DashboardStreamDto dto, CancellationToken ct = default)
    {
        var stream = await unitOfWork.UserRepository.GetDashboardStream(dto.Id, ct);
        if (stream == null) throw new KavitaException(await localizationService.TranslateAsync(userId, "dashboard-stream-doesnt-exist"));

        if (stream.AppUserId != userId)
        {
            throw new KavitaNotFoundException();
        }

        stream.Visible = dto.Visible;

        unitOfWork.UserRepository.Update(stream);
        await unitOfWork.CommitAsync(ct);
        await eventHub.SendMessageToAsync(MessageFactory.DashboardUpdate, MessageFactory.DashboardUpdateEvent(userId),
            userId, ct);
    }

    public async Task UpdateDashboardStreamPosition(int userId, UpdateStreamPositionDto dto,
        CancellationToken ct = default)
    {
        var user = await unitOfWork.UserRepository.GetUserByIdAsync(userId,

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Refresh the dashboard layout (GET /api/stream/dashboard) before editing visibility.
  2. Drop the update silently if the stream is no longer present.
  3. Guard the UI so updates target ids currently in the loaded layout.
Defensive patterns

Strategy: validation

Validate before calling

const dashboard = await api.get('/api/stream/dashboard');
if (!dashboard.some(d => d.id === dto.id)) {
  // stream no longer exists; nothing to update
  return;
}
await api.post('/api/stream/update-dashboard-stream', dto);

Type guard

function streamStillExists(id: number, dashboard: { id: number }[]): boolean {
  return dashboard.some(d => d.id === id);
}

Prevention

When it happens

Trigger: POST /api/stream/update-dashboard-stream with a DashboardStreamDto.Id that no longer exists (deleted stream, stale client state, id from another user).

Common situations: Client updates visibility for a stream that was removed elsewhere; restored/old layout cached in the browser; concurrent edits where one client deleted the stream.

Related errors


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/9bd9a1666c829a67. Report an issue: GitHub.