Summary
authsome documents that command failures in --json mode return structured JSON with error and message keys, but some CLI code paths bypass that contract.
The common @auth_command wrapper does the right thing when commands raise exceptions: it catches them and emits JSON through ContextObj.print_json(...). However, several command-specific paths print plain-text errors directly and then terminate with sys.exit(...). Those exits raise SystemExit, which bypasses the wrapper's except Exception handling.
As a result, callers using --json can still receive human-oriented plain text instead of the expected JSON error envelope.
Because authsome is intended to be used by agents to manage credentials, structured failure output is a core product requirement. Agent callers should not need fallback text parsing for nominal CLI errors.
Current behavior
The documented behavior is:
- when
--json is passed and a command fails, structured output includes error and message keys
But there are confirmed counterexamples today:
-
authsome get <provider> --field <missing> --json
- current output: plain text like
Field 'missing' not found.
- source:
src/authsome/cli/main.py writes the message directly and calls sys.exit(1) for an unknown field
-
authsome register <path> --yes --json with endpoint validation failure
- current output: plain text like
Error: authorization_url must use HTTPS scheme (...)
- source:
src/authsome/cli/helpers.py writes the message directly and calls sys.exit(1) from _validate_provider_endpoints(...)
-
authsome register <path> --yes --json when register_provider(...) raises
- current output: plain text like
Failed to register provider: ...
- source:
src/authsome/cli/main.py catches Exception, prints directly, and exits instead of letting @auth_command format the error
There may be adjacent cases with the same pattern, but these are already enough to show the inconsistency.
Why this matters
Agents and scripts rely on --json to make failure handling deterministic. A single plain-text error path forces downstream callers to add ad hoc text parsing or treat all CLI failures as potentially non-JSON, which defeats the point of the contract.
For an agent-oriented credential CLI, this is also a documentation mismatch: the current CLI reference promises structured JSON failures, but some commands do not honor it.
Proposed behavior
For commands running under @auth_command, error paths that should participate in --json handling should raise exceptions instead of printing directly and calling sys.exit(...).
That would allow the existing wrapper to preserve a single failure shape:
{
"v": 1,
"error": "SomeError",
"message": "..."
}
Scope
Confirmed areas to fix:
src/authsome/cli/main.py
- invalid
--field handling in get
register file/error paths that print directly and exit
src/authsome/cli/helpers.py
_validate_provider_endpoints(...)
Potential follow-up:
- audit other
@auth_command code paths for direct ctx_obj.echo(..., err=True) + sys.exit(...) combinations that should instead raise
Notes
This issue is specifically about error paths in --json mode.
It is not suggesting that every sys.exit(...) should be removed. Successful early exits and subprocess return-code propagation are fine. The problem is command-local error handling that bypasses the shared JSON error formatter.
Acceptance criteria
- In
--json mode, the confirmed failing commands above return structured JSON instead of plain text.
- Existing exit codes remain unchanged.
- The existing
{"v": 1, "error": ..., "message": ...} envelope is preserved.
- Tests cover at least the confirmed
get and register regressions.
- The documented
--json error behavior matches actual CLI behavior.
Summary
authsomedocuments that command failures in--jsonmode return structured JSON witherrorandmessagekeys, but some CLI code paths bypass that contract.The common
@auth_commandwrapper does the right thing when commands raise exceptions: it catches them and emits JSON throughContextObj.print_json(...). However, several command-specific paths print plain-text errors directly and then terminate withsys.exit(...). Those exits raiseSystemExit, which bypasses the wrapper'sexcept Exceptionhandling.As a result, callers using
--jsoncan still receive human-oriented plain text instead of the expected JSON error envelope.Because
authsomeis intended to be used by agents to manage credentials, structured failure output is a core product requirement. Agent callers should not need fallback text parsing for nominal CLI errors.Current behavior
The documented behavior is:
--jsonis passed and a command fails, structured output includeserrorandmessagekeysBut there are confirmed counterexamples today:
authsome get <provider> --field <missing> --jsonField 'missing' not found.src/authsome/cli/main.pywrites the message directly and callssys.exit(1)for an unknown fieldauthsome register <path> --yes --jsonwith endpoint validation failureError: authorization_url must use HTTPS scheme (...)src/authsome/cli/helpers.pywrites the message directly and callssys.exit(1)from_validate_provider_endpoints(...)authsome register <path> --yes --jsonwhenregister_provider(...)raisesFailed to register provider: ...src/authsome/cli/main.pycatchesException, prints directly, and exits instead of letting@auth_commandformat the errorThere may be adjacent cases with the same pattern, but these are already enough to show the inconsistency.
Why this matters
Agents and scripts rely on
--jsonto make failure handling deterministic. A single plain-text error path forces downstream callers to add ad hoc text parsing or treat all CLI failures as potentially non-JSON, which defeats the point of the contract.For an agent-oriented credential CLI, this is also a documentation mismatch: the current CLI reference promises structured JSON failures, but some commands do not honor it.
Proposed behavior
For commands running under
@auth_command, error paths that should participate in--jsonhandling should raise exceptions instead of printing directly and callingsys.exit(...).That would allow the existing wrapper to preserve a single failure shape:
{ "v": 1, "error": "SomeError", "message": "..." }Scope
Confirmed areas to fix:
src/authsome/cli/main.py--fieldhandling ingetregisterfile/error paths that print directly and exitsrc/authsome/cli/helpers.py_validate_provider_endpoints(...)Potential follow-up:
@auth_commandcode paths for directctx_obj.echo(..., err=True)+sys.exit(...)combinations that should instead raiseNotes
This issue is specifically about error paths in
--jsonmode.It is not suggesting that every
sys.exit(...)should be removed. Successful early exits and subprocess return-code propagation are fine. The problem is command-local error handling that bypasses the shared JSON error formatter.Acceptance criteria
--jsonmode, the confirmed failing commands above return structured JSON instead of plain text.{"v": 1, "error": ..., "message": ...}envelope is preserved.getandregisterregressions.--jsonerror behavior matches actual CLI behavior.