Skip to content

fix(vta): say which leg went quiet when a TSP reply times out - #345

Merged
stormer78 merged 1 commit into
mainfrom
worktree-persona-did-tsp-timeout
Sep 18, 2026
Merged

stormer78 merged 1 commit into
mainfrom
worktree-persona-did-tsp-timeout

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

What

Minting a persona DID fails with:

Failed to create persona DID: Failed to create DID via WebVH server:
tsp transport error: timed out waiting for the TSP reply to request 'urn:uuid:fa7c223d-…'

That names a transport and a UUID and nothing an operator can act on, and its
plain reading — "the VTA is unreachable" — is wrong.

Why the message is actively misleading

Diagnosed from a live VTA log plus the DID hosting control plane's own log:

  1. The VTA accepted the task and relayed it onward to the DID hosting server.
  2. The hosting server answered — promptly, within ~0.5s.
  3. The VTA refused every answer: refused a TSP frame that is not a binding envelope (got .../spec/trust-task-error/0.5).

So the reply the VTA sat waiting for was one it had already thrown away. Worse,
the VTA's self-repair (wait ~30s → re-relate → wait ~30s) outruns the SDK's
hard-coded 60s budget in create_did_webvh, so its real 500 lands a few
hundred milliseconds too late to be seen — 60.58s, 60.27s across the attempts in
the log. The timeout masks the diagnosis every time, by construction.

The root cause is not ours: affinidi-webvh-service never wired in the
binding/tsp/0.1 envelope on its TSP arm (the trust-tasks-tsp crate is
declared in its manifest and imported by nothing). That is fixed separately, in
that repo.

What this changes

Only legibility — R6.4, so the next operator opens the right log:

  • A TSP reply-timeout now says the request reached the VTA, and that the silent
    leg may be a peer's rather than ours.
  • Every VtaError picks up suggested_fix() — a public SDK method documented as
    existing for exactly this (non-CLI consumers that would otherwise fork the
    CLI's dispatch), which OpenVTC used nowhere.

Applied to the two WebVH-server-facing calls, the ones that traverse the
VTA→hosting-server leg. The original message, request id included, is kept — it
ties the TUI line to the VTA's own log entry for the same task.

Deliberately not changed

vta_retryable covers DidcommTransport but not TspTransport, which looks
like an oversight now TSP is the default transport. Widening it would override a
deliberate SDK safety decision — dids/create is Keyed in vta-sdk's
retry_safety table, so a blind retry risks a second orphan DID published in the
log — in order to fix a failure that retrying cannot fix anyway. Worth a separate
change if the retry story should consult that table rather than guess.

Testing

Two new tests pin both arms: a reply-timeout names the far leg and closes with
the SDK hint verbatim; any other TSP fault is not blamed on a far leg.

  • cargo fmt --all --check
  • cargo clippy --all-targets ✅ clean
  • RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --workspace
  • cargo test --workspace -- --include-ignored ✅ 1,440+ tests, 0 failures

Minting a persona DID fails with:

    Failed to create persona DID: Failed to create DID via WebVH server:
    tsp transport error: timed out waiting for the TSP reply to request
    'urn:uuid:fa7c223d-…'

which names a transport and a UUID and nothing an operator can act on.
Its plain reading — "the VTA is unreachable" — is wrong, and sends them
to the wrong log.

What actually happened in the reported case: the VTA accepted the task
and relayed it onward to the DID hosting server, the hosting server
answered promptly, and the VTA refused every answer because it was not
wrapped in the `binding/tsp/0.1/envelope`. The reply the VTA sat waiting
for was one it had already thrown away. The VTA's own self-repair (wait,
re-relate, wait again) then outruns the SDK's hard-coded 60s budget in
`create_did_webvh` by a few hundred milliseconds, so its real 500 always
lands too late to be seen — the timeout masks the diagnosis every time,
by construction.

None of that is ours to fix, and this change does not try to. It makes
the failure legible (R6.4): a reply-timeout now says the request reached
the VTA and that the silent leg may be a peer's rather than ours, so the
next operator opens the VTA's log instead of ours. Every VtaError also
picks up `suggested_fix()` — a public SDK method written for exactly this,
non-CLI consumers that would otherwise fork the CLI's dispatch, and which
OpenVTC used nowhere.

Applied to the two WebVH-server-facing calls, which are the ones that
traverse the VTA→hosting-server leg.

Left alone deliberately: `vta_retryable` covers `DidcommTransport` but
not `TspTransport`. Widening it would override a deliberate SDK safety
decision — `dids/create` is `Keyed` in vta-sdk's `retry_safety` table, so
a blind retry risks a second orphan DID published in the log — to fix a
failure that retrying cannot fix anyway.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 requested a review from a team as a code owner September 18, 2026 13:24
@stormer78
stormer78 merged commit cf57223 into main Sep 18, 2026
15 checks passed
@stormer78
stormer78 deleted the worktree-persona-did-tsp-timeout branch September 18, 2026 13:42
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.

1 participant