fix(errors): full agent-native APIError envelope + Capabilities() + live prod integration test#20
Merged
Merged
Conversation
P0: APIError dropped most of the API's canonical error envelope. The api
replies to every 4xx/5xx with {ok, error, error_code, message, agent_action,
upgrade_url, retry_after_seconds, request_id}, but APIError captured only
error + message — silently dropping agent_action, error_code, upgrade_url,
retry_after_seconds, and request_id. And Code was tagged json:"error" so it
held the category ("unauthorized"), not the canonical machine code
("missing_credentials" in error_code). This defeated the agent-native
contract: an agent had no next-step (agent_action), no upgrade path
(upgrade_url), no precise code to branch on, no request_id for support.
Fix:
- Add tagged fields ErrorCode, AgentAction, UpgradeURL,
RetryAfterSeconds (*int, to distinguish "retry in 0s" from "do not
retry"), and RequestID to APIError. Code/Message retained for back-compat.
- Add APIError.CanonicalCode() — prefers ErrorCode, falls back to Code — so
callers branch on the canonical machine code.
- Fold agent_action + upgrade_url into Error() so logs are actionable; the
legacy "(code): message" shape is unchanged when neither is present.
- Exported APIErrorEnvelopeKeys registry + rule-18 registry tests
(TestAPIError_EnvelopeKeysAllHaveAHome / …RegistryIsComplete /
…FullEnvelopeRoundTrips / …FullEnvelopeOverHTTP) so a future envelope key
can't silently drop. Existing APIError tests (DecodedFromBody, RawFallback,
RawOnly, Error string) still pass — backward compatible.
Add Client.Capabilities(ctx) → GET /api/v1/capabilities, returning the typed
tier matrix (*Capabilities / []TierCapabilities) plus a Raw map escape hatch
for forward compatibility. Six provider doc comments referenced this endpoint
with no method to call it; this is the first. Public/unauthenticated — works
in anonymous mode. Covered by capabilities_test.go.
Gate: go build ./... && go test ./... -short — green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…o CI Add a build-tagged (//go:build integration) live integration test that hits PROD https://api.instanode.dev and proves the agent-native error envelope fix against the real API: - unauthenticated GET /api/v1/resources → assert APIError carries agent_action + error_code (CanonicalCode) + upgrade_url - Capabilities() → assert the public tier matrix decodes and returns tiers Both are read-only / side-effect-free and skip cleanly when prod is unreachable from the runner. Wired into ci.yml as a new 'integration' job (go test -tags integration ... -run TestProdIntegration). Verified passing against prod: status=401 missing_credentials, agent_action + upgrade_url populated; 7 tiers returned. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
typos v1.47 flags RTO/rto (Recovery Time Objective) as 'should be TO'. These are real durability-SLO terms used by the Capabilities() API. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
diff-cover flagged capabilities.go:120-125 (re-encode + decode error paths). Re-encoding a decoded map can't fail, so decode the raw bytes directly into both the typed struct and Raw — removing the dead branch — and add a decode-error test for the type-mismatch path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Restores the full agent-native error envelope on the SDK's `APIError` and adds a typed `Capabilities()` surface, plus a build-tagged live integration test that proves the fix against PROD.
Fix (commit f9f1ab6)
Live prod integration test (commit 2f35668)
Verification (against live prod)
```
TestProdIntegration_APIErrorEnvelope — PASS
status=401 code="unauthorized" error_code="missing_credentials"
agent_action="...log in at https://instanode.dev/login..." upgrade_url="https://instanode.dev/login"
TestProdIntegration_Capabilities — PASS
7 tiers: anonymous, free, hobby, hobby_plus, pro, growth, team
```
Gate green: `go build ./... && go test ./... -short`. Build-tagged build/vet also clean.
🤖 Generated with Claude Code