a2aproject / a2aproject/a2a-js

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

Offen
#641 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
TypeScript
Sterne
613
Forks
169
Ø Merge
1 T. 6 Std.
Gemergte PRs (30 T.)
21

Beschreibung

### What happened?

`google.protobuf.Timestamp` fields are passed straight through as strings. The generated
code is:

```ts
timestamp: isSet(object.timestamp) ? globalThis.String(object.timestamp) : undefined,
```

and `toJSON` copies it back out unchanged. Nothing parses it and nothing checks it, which
causes two separate problems.

**Malformed timestamps are accepted and forwarded.** Every one of these is stored and
re-emitted verbatim:

```js
import { TaskStatus } from '@a2a-js/sdk';
const ts = (t) => TaskStatus.toJSON(TaskStatus.fromJSON({ state: 'TASK_STATE_WORKING', timestamp: t }));

ts('not-a-timestamp'); // { state: 'TASK_STATE_WORKING', timestamp: 'not-a-timestamp' }
ts(''); // { ..., timestamp: '' }
ts(12345); // { ..., timestamp: '12345' } a JSON number becomes a string
```

`a2a-python` rejects all of them. So a JS server accepts a `Task` whose
`status.timestamp` is arbitrary text, hands it downstream, and the Python peer is the one
that throws. The component that let the bad data in isn't the component that reports it,
which makes this annoying to track down in a mixed deployment.

**Offsets are never normalized.** proto3 JSON output is always Z-normalized.
`a2a-python` does that; this SDK keeps whatever offset arrived:

```
input "2026-01-01T05:30:00+05:30"
python "2026-01-01T00:00:00Z"
js "2026-01-01T05:30:00+05:30"
```

Same instant, different bytes. That's fine until something compares bytes rather than
instants, which is what canonicalization does. `src/signature.ts:188` canonicalizes via
`AgentCard.toJSON(AgentCard.fromJSON(card))`, so this codec sits on the signing path.

Storing the field unparsed also means any timestamp comparison or ordering inside the SDK
is operating on a string whose format isn't guaranteed.

### What I'd expect

`fromJSON` parses and validates RFC 3339, rejecting input that isn't a timestamp, and
`toJSON` emits the Z-normalized form.

### How this was found

Round-tripping a shared corpus through this SDK and `a2a-python` and diffing the JSON.
Both generate from the same `.proto`.

Reproduced on `@a2a-js/sdk` 1.0.1 from npm and on `main` at `1c6eb32`, against
`a2a-python` at `cff6727`.

Same question as the other codec issues I'm filing: this is in the generated
`src/types/pb/a2a.ts`, so tell me where you'd like the fix and I'll send it.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

The issue is in the generated file `src/types/pb/a2a.ts`. Look for the `google.protobuf.Timestamp` field handling in `fromJSON` and `toJSON`. The fix involves parsing and validating RFC 3339 timestamps, normalizing to UTC, and ensuring malformed inputs are rejected. Check how `a2a-python` implements this for reference. Run existing tests to verify the changes don't break existing functionality.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
api, backend
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Aktiv
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
55/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.