Skip to content

fix(dashboard): guard task detail log rendering - #1677

Merged
gsxdsm merged 2 commits into
Runfusion:mainfrom
plarson:fix/task-detail-log-entry-rendering
Jun 15, 2026
Merged

fix(dashboard): guard task detail log rendering#1677
gsxdsm merged 2 commits into
Runfusion:mainfrom
plarson:fix/task-detail-log-entry-rendering

Conversation

@plarson

@plarson plarson commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Guard task detail activity-log rendering when a persisted log entry uses legacy/operator text/detail fields instead of action/outcome.
  • Reuse the same safe action extraction for in-review and stale-review log matching.
  • Add regression coverage for malformed/operator-shaped entries so a single bad log row cannot crash the issue detail section.

Root cause

A live Atlas Notes task had an operator activity entry shaped as { text, detail, type }. TaskDetailModal assumed every activity entry had entry.action and called entry.action.match(...), which crashed the section with undefined is not an object.

Verification

  • corepack pnpm --filter @fusion/dashboard exec vitest run app/__tests__/task-log-entry-display.test.ts --silent=passed-only --reporter=dot
  • corepack pnpm --filter @fusion/dashboard typecheck
  • corepack pnpm --filter @fusion/dashboard build

Summary by CodeRabbit

  • Bug Fixes
    • Improved task detail activity log rendering to correctly handle legacy activity log entries by deriving action/outcome values for stall matching (“in-review” and “stale paused review”) and for the activity timeline display.
  • Tests
    • Added Vitest coverage for task log entry display helpers and log scanning, including legacy text/detail mapping, empty/fallback behavior, malformed inputs, and safe handling when actions are missing.
  • Chores
    • Added a patch changeset for the dashboard package.

Copilot AI review requested due to automatic review settings June 14, 2026 20:35
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 224fc062-75df-45ef-8898-b3a8b1e10917

📥 Commits

Reviewing files that changed from the base of the PR and between 84cf3ff and 724f31a.

📒 Files selected for processing (1)
  • packages/dashboard/app/utils/inReviewStallCopy.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/dashboard/app/utils/inReviewStallCopy.ts

📝 Walkthrough

Walkthrough

Adds TaskLogEntryLike type and two helper functions (getTaskLogEntryAction, getTaskLogEntryOutcome) that fall back to legacy text/detail fields when action/outcome are absent. Updates findInReviewStallLogEntry, inReviewStallCopy, and TaskDetailModal to use these helpers, and adds tests plus a patch changeset.

Changes

Legacy Log Entry Field Compatibility

Layer / File(s) Summary
TaskLogEntryLike type and display helpers
packages/dashboard/app/utils/taskLogEntryDisplay.ts
Exports TaskLogEntryLike (a Partial<TaskLogEntry> with unknown-typed action, outcome, text, detail), getTaskLogEntryAction (returns action → fallback text""), and getTaskLogEntryOutcome (returns outcome → fallback detailundefined).
findInReviewStallLogEntry integration
packages/dashboard/app/utils/findInReviewStallLogEntry.ts
Imports getTaskLogEntryAction and uses it to derive the log entry's action when matching the "in-review stall surfaced" regex pattern instead of reading entry.action directly.
inReviewStallCopy integration
packages/dashboard/app/utils/inReviewStallCopy.ts
Imports getTaskLogEntryAction and uses it in getInReviewStallDeadlockCopy to detect deadlock logs by deriving each log entry's action for prefix matching instead of reading entry.action.
TaskDetailModal integration
packages/dashboard/app/components/TaskDetailModal.tsx
Imports both helpers and applies them throughout activity timeline rendering (stall-highlight matching, activity log display values) and stale-paused-review badge lookup, replacing direct entry.action and entry.outcome reads.
Tests and changeset
packages/dashboard/app/__tests__/task-log-entry-display.test.ts, .changeset/guard-task-detail-log-entry-shape.md
Vitest suite covers legacy fallback, malformed-input safety, and findInReviewStallLogEntry robustness when entries omit action. Changeset documents the patch bump.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested reviewers

  • gsxdsm

Poem

🐇 Hop, hop, I found some old logs without action or flair,
So I check for text and detail hiding there.
getTaskLogEntryAction leaps with care,
Fallback fields now handled with a graceful snare.
No more blank stalls — every log gets its share! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(dashboard): guard task detail log rendering' directly and concisely summarizes the main change: adding guards to protect task detail log entry rendering from crashes when entries have legacy field structures.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR hardens task activity-log parsing/rendering in the dashboard so legacy/operator-shaped log entries (using text/detail) don’t break UI features that expect action/outcome.

Changes:

  • Added getTaskLogEntryAction / getTaskLogEntryOutcome helpers with safe fallbacks.
  • Updated stall-log scanning and Task Detail log rendering to use the helpers.
  • Added Vitest coverage for legacy/malformed log-entry handling.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/dashboard/app/utils/taskLogEntryDisplay.ts Introduces helper functions and a “like” type for safely extracting display strings from mixed-shape log entries.
packages/dashboard/app/utils/findInReviewStallLogEntry.ts Uses the new helper to avoid .match on missing/non-string action.
packages/dashboard/app/components/TaskDetailModal.tsx Updates UI rendering and regex matching to rely on safe action/outcome extraction.
packages/dashboard/app/tests/task-log-entry-display.test.ts Adds test coverage for fallback behavior and non-throwing stall scanning.
.changeset/guard-task-detail-log-entry-shape.md Records a patch changeset describing the guard behavior change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/dashboard/app/utils/taskLogEntryDisplay.ts Outdated
Comment thread packages/dashboard/app/utils/taskLogEntryDisplay.ts
Comment thread packages/dashboard/app/__tests__/task-log-entry-display.test.ts Outdated
@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Guards all activity-log rendering in TaskDetailModal (and supporting utilities) against persisted log entries that use legacy text/detail fields instead of the modern action/outcome shape, fixing a live crash on Atlas Notes tasks with operator-authored entries.

  • New helper taskLogEntryDisplay.ts: getTaskLogEntryAction / getTaskLogEntryOutcome safely extract display strings with fallback to text/detail and full null/undefined protection; three call-sites in TaskDetailModal, findInReviewStallLogEntry, and inReviewStallCopy are updated.
  • Regression tests added: five Vitest cases cover legacy mapping, malformed entries, whitespace-only fallback, and safe log scanning in both stall-entry finders.
  • taskTiming.ts left untouched intentionally: it already used || / ?? guards that make it safe against missing action fields, so no change was needed there.

Confidence Score: 5/5

Safe to merge — the change is a targeted crash guard with no behavioral changes to the happy path, and all four affected code sites have been updated.

All direct entry.action accesses in the rendering and stall-detection paths are replaced with the new safe helpers. taskTiming.ts already used || / ?? guards that make it safe. The new utility has clear fallback semantics, and five regression tests confirm the crash-prone scenarios now return safe values instead of throwing.

No files require special attention.

Important Files Changed

Filename Overview
packages/dashboard/app/utils/taskLogEntryDisplay.ts New utility that safely extracts action/outcome from log entries, with fallback to legacy text/detail fields and null/undefined guards throughout.
packages/dashboard/app/components/TaskDetailModal.tsx Replaces all direct entry.action accesses (3 sites) with getTaskLogEntryAction/getTaskLogEntryOutcome calls; grep confirms no remaining raw entry.action access in the file.
packages/dashboard/app/utils/findInReviewStallLogEntry.ts Single-site fix routes the regex match through getTaskLogEntryAction, eliminating the crash when a legacy entry has no action field.
packages/dashboard/app/utils/inReviewStallCopy.ts Deadlock-copy detection now routes entry.action through the safe helper; log scanning can no longer crash when iterating mixed legacy/modern entries.
packages/dashboard/app/tests/task-log-entry-display.test.ts New regression suite covers legacy text/detail mapping, malformed entries, blank-action fallback, and safe scanning in both findInReviewStallLogEntry and getInReviewStallDeadlockCopy.
.changeset/guard-task-detail-log-entry-shape.md Patch changeset entry describing the legacy log-entry guard fix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Task log entry from DB] --> B{has action field?}
    B -- "yes, non-blank" --> C[use entry.action]
    B -- "no / blank" --> D{has text field?}
    D -- "yes, non-blank" --> E[use entry.text]
    D -- "no" --> F[return empty string]

    G[Task log entry from DB] --> H{has outcome field?}
    H -- "yes, non-blank" --> I[use entry.outcome]
    H -- "no / blank" --> J{has detail field?}
    J -- "yes, non-blank" --> K[use entry.detail]
    J -- "no" --> L[return undefined]

    C --> M[regex match / render]
    E --> M
    F --> M

    I --> N[render outcome div]
    K --> N
    L --> O[skip outcome div]
Loading

Reviews (4): Last reviewed commit: "fix(dashboard): document legacy task log..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/dashboard/app/utils/taskLogEntryDisplay.ts (1)

1-29: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add FNXC_LOG comments per coding guidelines.

The coding guidelines require FNXC comments for all important changes in packages/**/*.{ts,tsx,js,jsx} files. Add a jsdoc comment above each function describing the date (format yyyy-MM-dd-hh:mm) and the requirement it addresses (fallback for legacy log entry fields).

📝 Suggested documentation
 import type { TaskLogEntry } from "`@fusion/core`";
 
 export type TaskLogEntryLike = Partial<TaskLogEntry> & {
   action?: unknown;
   outcome?: unknown;
   text?: unknown;
   detail?: unknown;
 };
 
+/**
+ * FNXC:TaskDetail 2026-06-14 Extract action string from log entry with fallback to legacy 'text' field.
+ * Requirement: Task detail activity log must not crash when rendering legacy/operator log entries
+ * that use text/detail instead of action/outcome fields.
+ */
 export function getTaskLogEntryAction(entry: TaskLogEntryLike | null | undefined): string {
   if (typeof entry?.action === "string") {
     return entry.action;
   }
   if (typeof entry?.text === "string") {
     return entry.text;
   }
   return "";
 }
 
+/**
+ * FNXC:TaskDetail 2026-06-14 Extract optional outcome string from log entry with fallback to legacy 'detail' field.
+ * Requirement: Task detail activity log must not crash when rendering legacy/operator log entries
+ * that use text/detail instead of action/outcome fields.
+ */
 export function getTaskLogEntryOutcome(entry: TaskLogEntryLike | null | undefined): string | undefined {
   if (typeof entry?.outcome === "string" && entry.outcome.length > 0) {
     return entry.outcome;
   }
   if (typeof entry?.detail === "string" && entry.detail.length > 0) {
     return entry.detail;
   }
   return undefined;
 }

As per coding guidelines, add FNXC comments describing the date of the change (format yyyy-MM-dd-hh:mm) and describing the requirements or the change in requirements. Write FNXC:Area-of-product in front of all comments. Write most of this as jsdocs but add short comments for important variables and complex parts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/utils/taskLogEntryDisplay.ts` around lines 1 - 29, Add
FNXC jsdoc comments above both the getTaskLogEntryAction and
getTaskLogEntryOutcome functions per coding guidelines. Each comment should
include the current date in yyyy-MM-dd-hh:mm format, reference the
FNXC:Area-of-product format, and describe that the functions provide fallback
support for legacy log entry fields (action/text for getTaskLogEntryAction and
outcome/detail for getTaskLogEntryOutcome).

Source: Coding guidelines

packages/dashboard/app/components/TaskDetailModal.tsx (1)

3239-3270: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add FNXC comment documenting the log entry display change.

Per coding guidelines, add a short FNXC comment above line 3242 noting the date and requirement: safe extraction of action/outcome from log entries that may use legacy text/detail fields.

📝 Suggested comment
                       {(() => {
                         let highlightedOnce = false;
                         return [...workingTask.log].reverse().map((entry, i) => {
+                          // FNXC:TaskDetail 2026-06-14 Safe extraction with fallback to legacy text/detail fields
                           const action = getTaskLogEntryAction(entry);
                           const outcome = getTaskLogEntryOutcome(entry);
                           const stallMatch = action.match(IN_REVIEW_STALL_LOG_REGEX)

As per coding guidelines, add FNXC:Area-of-product in front of all comments and describe the requirements or the change in requirements.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/components/TaskDetailModal.tsx` around lines 3239 -
3270, Add a FNXC comment above the highlightedOnce variable declaration in the
anonymous function that maps workingTask.log entries. The comment should follow
the format "FNXC:Area-of-product" and document the requirement that the
getTaskLogEntryAction and getTaskLogEntryOutcome function calls safely extract
action and outcome from log entries that may use legacy text/detail fields,
noting when this requirement was established.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/dashboard/app/components/TaskDetailModal.tsx`:
- Around line 3239-3270: Add a FNXC comment above the highlightedOnce variable
declaration in the anonymous function that maps workingTask.log entries. The
comment should follow the format "FNXC:Area-of-product" and document the
requirement that the getTaskLogEntryAction and getTaskLogEntryOutcome function
calls safely extract action and outcome from log entries that may use legacy
text/detail fields, noting when this requirement was established.

In `@packages/dashboard/app/utils/taskLogEntryDisplay.ts`:
- Around line 1-29: Add FNXC jsdoc comments above both the getTaskLogEntryAction
and getTaskLogEntryOutcome functions per coding guidelines. Each comment should
include the current date in yyyy-MM-dd-hh:mm format, reference the
FNXC:Area-of-product format, and describe that the functions provide fallback
support for legacy log entry fields (action/text for getTaskLogEntryAction and
outcome/detail for getTaskLogEntryOutcome).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 92e422e1-631b-4de6-b6be-d075752ed91b

📥 Commits

Reviewing files that changed from the base of the PR and between 23c2bc9 and 34cf56b.

📒 Files selected for processing (5)
  • .changeset/guard-task-detail-log-entry-shape.md
  • packages/dashboard/app/__tests__/task-log-entry-display.test.ts
  • packages/dashboard/app/components/TaskDetailModal.tsx
  • packages/dashboard/app/utils/findInReviewStallLogEntry.ts
  • packages/dashboard/app/utils/taskLogEntryDisplay.ts

@plarson
plarson force-pushed the fix/task-detail-log-entry-rendering branch from 34cf56b to bcfb1e9 Compare June 14, 2026 20:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/dashboard/app/utils/inReviewStallCopy.ts (1)

113-120: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add FNXC JSDoc comment documenting the legacy log entry handling.

This function now handles legacy log entry formats via getTaskLogEntryAction, which prevents crashes when log entries lack the action field—an important behavioral change that should be documented.

📝 Suggested JSDoc
+/**
+ * FNXC:TaskLogs YYYY-MM-DD-HH:MM
+ * Detects whether a task was auto-disposed due to in-review stall deadlock.
+ * Uses getTaskLogEntryAction to handle legacy log entries that may lack the action field,
+ * preventing crashes when rendering activity logs with operator or legacy-shaped entries.
+ */
 export function getInReviewStallDeadlockCopy(task: Pick<Task, "pausedReason" | "log">): InReviewStallDeadlockCopy | undefined {

As per coding guidelines, changes should include FNXC comments with dates (format yyyy-MM-dd-hh:mm) and requirement descriptions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/utils/inReviewStallCopy.ts` around lines 113 - 120,
Add a FNXC JSDoc comment to the getInReviewStallDeadlockCopy function that
documents the legacy log entry handling behavior. The comment should explain
that the function uses getTaskLogEntryAction to safely handle legacy log entry
formats that may lack the action field, which prevents crashes when processing
older log data. Include the FNXC comment with a date in yyyy-MM-dd-hh:mm format
and a brief requirement description explaining the purpose of this backward
compatibility handling.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/dashboard/app/utils/inReviewStallCopy.ts`:
- Around line 113-120: Add a FNXC JSDoc comment to the
getInReviewStallDeadlockCopy function that documents the legacy log entry
handling behavior. The comment should explain that the function uses
getTaskLogEntryAction to safely handle legacy log entry formats that may lack
the action field, which prevents crashes when processing older log data. Include
the FNXC comment with a date in yyyy-MM-dd-hh:mm format and a brief requirement
description explaining the purpose of this backward compatibility handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5cc80a80-3280-411a-8c0f-f0ea513c2ebb

📥 Commits

Reviewing files that changed from the base of the PR and between 34cf56b and bcfb1e9.

📒 Files selected for processing (6)
  • .changeset/guard-task-detail-log-entry-shape.md
  • packages/dashboard/app/__tests__/task-log-entry-display.test.ts
  • packages/dashboard/app/components/TaskDetailModal.tsx
  • packages/dashboard/app/utils/findInReviewStallLogEntry.ts
  • packages/dashboard/app/utils/inReviewStallCopy.ts
  • packages/dashboard/app/utils/taskLogEntryDisplay.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/guard-task-detail-log-entry-shape.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/dashboard/app/tests/task-log-entry-display.test.ts
  • packages/dashboard/app/utils/taskLogEntryDisplay.ts
  • packages/dashboard/app/utils/findInReviewStallLogEntry.ts
  • packages/dashboard/app/components/TaskDetailModal.tsx

@plarson
plarson force-pushed the fix/task-detail-log-entry-rendering branch from bcfb1e9 to 84cf3ff Compare June 14, 2026 20:50
@gsxdsm
gsxdsm merged commit a2f5dd4 into Runfusion:main Jun 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants