Skip to content

fix(types): validate RFC 3339 timestamp and normalize to UTC in codecs - #656

Open
Varun-S10 wants to merge 1 commit into
a2aproject:mainfrom
Varun-S10:fix/issue-641
Open

fix(types): validate RFC 3339 timestamp and normalize to UTC in codecs#656
Varun-S10 wants to merge 1 commit into
a2aproject:mainfrom
Varun-S10:fix/issue-641

Conversation

@Varun-S10

Copy link
Copy Markdown
Contributor

Description

Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:

  • Follow the CONTRIBUTING Guide.
  • Make your Pull Request title in the https://www.conventionalcommits.org/ specification.
    • Important Prefixes for release-please:
      • fix: which represents bug fixes, and correlates to a SemVer patch.
      • feat: represents a new feature, and correlates to a SemVer minor.
      • feat!:, or fix!:, refactor!:, etc., which represent a breaking change (indicated by the !) and will result in a SemVer major.
  • Ensure the tests and linter pass
  • Appropriate docs were updated (if necessary)

Fixes #641 🦕


What was the bug?

In the A2A protobuf specification, TaskStatus.timestamp and ListTasksRequest.status_timestamp_after are typed as google.protobuf.Timestamp. According to the proto3 JSON specification:

  1. Timestamps must be valid RFC 3339 formatted strings.
  2. Timezone offsets (such as +05:30 or -05:00) must be normalized to UTC (Z).
  3. Malformed non-timestamp inputs must be rejected with an error.

Previously, TaskStatus.fromJSON and ListTasksRequest.fromJSON passed timestamp inputs straight through as raw strings using globalThis.String(object.timestamp) without validation or normalization:

  • Malformed inputs like "not-a-timestamp", "", or 12345 were accepted without error and forwarded downstream, causing a2a-python peers to crash when receiving them.
  • Timezone offsets (e.g., "2026-01-01T05:30:00+05:30") were never converted to UTC ("2026-01-01T00:00:00Z"), leading to byte-level mismatches during card signing and canonicalization.

How is it fixed?

  1. src/types/pb/a2a.ts:
    • Added fromJsonTimestamp helper that validates RFC 3339 date strings, throws a descriptive error on invalid inputs ("not-a-timestamp", "", 12345, boolean, object), and normalizes non-UTC timezone offsets to UTC (Z).
    • Updated TaskStatus.fromJSON and ListTasksRequest.fromJSON to use fromJsonTimestamp.
  2. test/types/timestamp.spec.ts:
    • Added 14 unit test cases covering already-normalized UTC strings, positive/negative offset normalization, subsecond preservation, Date instances, and strict rejection of invalid values.

Verification

  • TaskStatus.fromJSON and ListTasksRequest.fromJSON throw on malformed/empty/numeric timestamps.
  • Non-UTC timezone offsets normalize to UTC "2026-01-01T00:00:00Z".
  • Unit tests in test/types/timestamp.spec.ts passed (14/14).
  • Full test suite (npm test) passed (69/69 test files, 1,501 tests).
  • ESLint and TypeScript checks (npm run lint) passed with 0 errors.
  • Build and bundle checks (npm run build && npm run test-build) passed cleanly.

@Varun-S10
Varun-S10 requested a review from a team as a code owner August 14, 2026 06:37
@github-actions

Copy link
Copy Markdown

🧪 Code Coverage

⬇️ Download Full Report

No coverage changes.

Generated by coverage-comment.yml

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.

[Bug]: Timestamp fields are unvalidated strings and are never normalized to UTC

1 participant