Skip to content

Fix ISO8601 date parsing crash for task and project date fields#25

Open
Lumenbeing wants to merge 2 commits into
deverman:masterfrom
Lumenbeing:fix/tolerant-date-parsing
Open

Fix ISO8601 date parsing crash for task and project date fields#25
Lumenbeing wants to merge 2 commits into
deverman:masterfrom
Lumenbeing:fix/tolerant-date-parsing

Conversation

@Lumenbeing
Copy link
Copy Markdown

Summary

Requesting any date field (dueDate, plannedDate, deferDate, completionDate, lastReviewDate, nextReviewDate) on list-tasks or list-projects causes a bridge timeout with:

Error: Automation execution failed: Bridge response timed out after 45.0s
lastReadError=dataCorrupted(...debugDescription: "Expected date string to be ISO8601-formatted.")

The root cause is that the JSONDecoder in BridgeClient uses Swift's strict .iso8601 date decoding strategy, which only accepts yyyy-MM-dd'T'HH:mm:ssZ. OmniFocus's bridge plugin can return dates in other valid ISO 8601 variants (with fractional seconds, without timezone, or date-only).

Fix

Replace the single-format .iso8601 decoder with a .custom strategy that tries multiple formats in order:

  1. ISO 8601 with fractional seconds (2026-04-04T12:00:00.000Z)
  2. ISO 8601 standard (2026-04-04T12:00:00Z)
  3. Date-only (2026-04-04)
  4. ISO 8601 without timezone (2026-04-04T12:00:00)

Only BridgeClient.swift is changed — one-line replacement of the decoder strategy.

Test plan

  • swift build passes
  • focusrelay list-projects --fields id,name,lastReviewDate,nextReviewDate,completionDate returns dates correctly (previously crashed)
  • focusrelay list-tasks --fields id,name,dueDate,plannedDate,deferDate,completionDate returns dates correctly (previously crashed)
  • Non-date fields continue to work as before

The bridge plugin returns dates from OmniFocus in formats that Swift's
built-in .iso8601 JSONDecoder strategy cannot parse (e.g., dates without
fractional seconds, date-only strings, or timestamps without timezone).

This caused "Expected date string to be ISO8601-formatted" errors and
45-second bridge timeouts when requesting any date field (dueDate,
plannedDate, deferDate, completionDate, lastReviewDate, nextReviewDate)
on list-tasks or list-projects.

Replace the strict .iso8601 decoder with a .custom strategy that tries
multiple formats in order:
1. ISO8601 with fractional seconds
2. ISO8601 standard (withInternetDateTime)
3. Date-only (yyyy-MM-dd)
4. ISO8601 without timezone

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mikehohnen-web
Copy link
Copy Markdown

This would fix my issue (#26). I'm on a European locale (DD/MM/YYYY) and every date field query crashes with the same ISO8601 error. Happy to test if helpful.

@deverman
Copy link
Copy Markdown
Owner

deverman commented Apr 9, 2026

Follow-up on the direction of this fix:

After reviewing the bridge contract more closely, I narrowed the implementation to match the formats the bridge actually emits instead of broadly accepting multiple unrelated date variants.

The bridge plugin serializes OmniFocus Date values with toISOString(), so the practical formats we need to support are:

  • 2026-04-04T12:00:00Z
  • 2026-04-04T12:00:00.000Z

Based on that, the branch has been adjusted to:

  • add a shared bridge date-decoding helper
  • use it in both BridgeClient and OmniAutomationService
  • accept standard ISO8601 and fractional-second ISO8601
  • reject unsupported formats outside the bridge contract
  • add regression tests that verify exact decoded timestamps for task and project payloads

This keeps the fix aligned with the real transport format, avoids broadening the parsing contract without evidence, and removes the per-date formatter allocation from the original patch shape.

Manual validation I recommend on a machine that can operate OmniFocus correctly:

  • swift build
  • swift test --filter BridgeDateDecoding
  • swift run focusrelay bridge-health-check
  • swift run focusrelay list-projects --fields id,name,lastReviewDate,nextReviewDate,completionDate --limit 5
  • swift run focusrelay list-tasks --fields id,name,dueDate,plannedDate,deferDate,completionDate --limit 5

Expected result:

  • date-field queries no longer fail in the Swift decode layer
  • both bridge and JXA decode paths use the same date parsing behavior
  • standard and fractional ISO8601 bridge timestamps decode correctly

@deverman
Copy link
Copy Markdown
Owner

deverman commented Apr 9, 2026

@mikehohnen-web @Lumenbeing unfortunately I can't reproduce this error. I tried to narrow this down and made another commit. Can you confirm if the fix works?

@mikehohnen-web
Copy link
Copy Markdown

Thanks for the quick response. I'm happy to test when a new release is available via Homebrew. My issue is #25— European locale (DD/MM/YYYY) on macOS, every date field query fails.

Copy link
Copy Markdown
Owner

I added a follow-up diagnostic request on issue #26 so we can gather more concrete environment/runtime details from the reporter.

The main thing I was trying to separate is:

  • Sequoia vs Tahoe Foundation behavior
  • locale-only formatting differences
  • plugin/install mismatch
  • data-specific edge cases

On my Tahoe 26.4.1 machine, I still could not reproduce the failure even after switching to an en-FR / da-FR style locale stack, so I asked for targeted command output from the reporter here:

#26 (comment)

Once they reply, we should have a much better sense of whether the PR is fixing a runtime-specific decode issue or whether there is a separate repro condition we have not captured yet.

@deverman
Copy link
Copy Markdown
Owner

@Lumenbeing were you able to test the fix I created? Can you confirm what macOS version you are running on?

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.

4 participants