cli icon indicating copy to clipboard operation
cli copied to clipboard

Fix AssertionError when METHOD appears before options

Open ns-fboucault opened this issue 1 month ago • 0 comments

Fixes #1614

Problem

When the HTTP method (POST, GET, etc.) was specified before optional arguments like --auth-type, an AssertionError was raised due to incorrect argument parsing.

Example failing command:

http POST --auth-type bearer --auth TOKEN https://example.org

Root Cause

Argparse's nargs=OPTIONAL for the METHOD argument doesn't work well with intermixed arguments. When METHOD appears before optional flags, argparse incorrectly parsed:

  • method=None
  • url='POST' (the method string)
  • URL and request items ended up in unparsed arguments

The assertion at line 416 in _guess_method() failed because it expected no request_items when method is None.

Solution

Added a new _fix_argument_order() method that:

  1. Detects when arguments were misparsed (method is None, url looks like HTTP method, unparsed args present)
  2. Correctly reassigns the values: method from url, url from first unparsed arg
  3. Parses remaining unparsed arguments as request items atomically (all or nothing)
  4. Properly initializes request_items if it's None
  5. Runs before _apply_no_options() to prevent errors from unrecognized arguments

Changes Made

  • httpie/cli/argparser.py: Added _fix_argument_order() method (48 lines)
  • tests/test_cli.py: Added 2 unit tests for the fix
  • tests/test_auth.py: Added integration test with bearer auth

Testing

✅ All 71 existing tests pass
✅ New tests verify the fix works correctly
✅ Tested with original failing command from issue #1614
✅ Backward compatibility maintained

Additional Notes

The fix handles two important edge cases:

  1. Atomicity: All request items are validated before any are added to prevent partial parsing
  2. NoneType safety: Initializes request_items to [] if None before extending

Example Commands Now Working

# Original failing command
http POST --auth-type bearer --auth TOKEN https://example.org

# With request items
http POST --auth-type bearer --auth TOKEN https://example.org foo=bar

# Other HTTP methods
http GET --auth-type bearer --auth TOKEN https://example.org
http PUT --verbose https://example.org

ns-fboucault avatar Nov 21 '25 21:11 ns-fboucault