fix(tasks): guard ShortSyntaxEffects against undefined task during concurrent sync

When a WebSocket-triggered archive sync applies a moveToArchive operation
concurrently with a local rename, the ShortSyntaxEffects' getByIdOnce$()
call returns undefined because the task has already been moved out of the
active NgRx store. Calling shortSyntax(undefined, ...) then throws a
TypeError that triggers a global error dialog, blocking UI interactions
such as navigating to the worklog.

Fix: add an early-return EMPTY guard after getByIdOnce$() resolves so
the effect silently no-ops when the task no longer exists in the store.
This commit is contained in:
Johannes Millan 2026-04-14 16:48:42 +02:00
parent 791fa533e7
commit 309670db3a

View file

@ -17,7 +17,7 @@ import {
import { GlobalConfigService } from '../../config/global-config.service';
import { unique } from '../../../util/unique';
import { TaskService } from '../task.service';
import { from, of } from 'rxjs';
import { EMPTY, from, of } from 'rxjs';
import { ProjectService } from '../../project/project.service';
import { TagService } from '../../tag/tag.service';
import { shortSyntax } from '../short-syntax';
@ -102,6 +102,12 @@ export class ShortSyntaxEffects {
),
),
mergeMap(([{ task, originalAction }, tags, projects, defaultProjectId]) => {
// Guard: task may have been archived/deleted while the effect was in flight
// (e.g., a concurrent sync applied a moveToArchive op). Skip processing
// to prevent "Cannot read properties of undefined" errors.
if (!task) {
return EMPTY;
}
const isReplaceTagIds = originalAction.type === TaskSharedActions.updateTask.type;
return from(
shortSyntax(