Skip to content

feat: machine-readable JSON error output for -o json #29

Description

@msampathkumar

Goal: Make a2a failures machine-readable under -o json, so a program can handle an error the same way it handles a result.
User story: As a program or agent consuming -o json, I want failures returned as a JSON object just like successes, so that I can detect and branch on errors with a single JSON parse instead of scraping stderr.

Priority: P0 · Area: CLI code

Problem

On failure the tool prints a human-readable Error: <text> line to stderr — even when the caller asked for -o json. A program gets a parseable object on success but an unparseable plaintext line on failure.

$ a2a card get http://127.0.0.1:9999 -o json     # nothing listening
Error: failed to resolve agent card: ... connect: connection refused

$ a2a send --bogus -o json 'x'
Error: unknown flag: --bogus

Proposed behavior

Under -o json, a failure emits exactly one error object on stdout (diagnostics stay on stderr):

{
  "error": {
    "code":    "string",
    "message": "human-readable string",
    "hint":    "actionable next step, or null",
    "a2aCode": "underlying transport code, or null"
  }
}
  • code — a protocol error carries the agent's error name (e.g. TaskNotFoundError); a CLI-local condition carries a symbolic A2ACLI_ERR_* code.
  • Proposed CLI-local codes: A2ACLI_ERR_USAGE, A2ACLI_ERR_CARD_NOT_FOUND, A2ACLI_ERR_CARD_INVALID, A2ACLI_ERR_UNREACHABLE, A2ACLI_ERR_CREDENTIALS_MISSING, A2ACLI_ERR_AUTH_FAILED, A2ACLI_ERR_TIMEOUT, A2ACLI_ERR_INTERNAL.
  • hint — a short, copy-pasteable next step when one exists, else null.

Examples:

{"error":{"code":"A2ACLI_ERR_CARD_NOT_FOUND","message":"no agent card at http://127.0.0.1:9999","hint":"check the --agent-card reference","a2aCode":null}}
{"error":{"code":"A2ACLI_ERR_USAGE","message":"unknown flag: --bogus","hint":"run: a2a send --help","a2aCode":null}}

Under --stream, an error that terminates the stream is emitted as a final error object on its own line. text mode may keep the readable Error: line.

Acceptance criteria

  • -o json failures emit the error object on stdout; nothing but structured output on stdout.
  • Protocol failures carry the agent's error name; CLI-local failures carry an A2ACLI_ERR_* code.
  • hint populated where an actionable next step exists.
  • Tests cover: unresolvable card, usage error, and a protocol error.

Environment

  • CLI version: a2a version v0.0.0-…1e29dfe94f95+dirty
  • OS: Linux x86_64

Notes

Pairs with the distinct-exit-codes request — both live in Execute()/error handling (internal/cli/root.go); the reported code and the exit code should agree.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Priority 0 — wrong/unsafe today or scripting blockerenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions