Fix AssertionError when METHOD appears before options
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=Noneurl='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:
- Detects when arguments were misparsed (method is None, url looks like HTTP method, unparsed args present)
- Correctly reassigns the values: method from url, url from first unparsed arg
- Parses remaining unparsed arguments as request items atomically (all or nothing)
- Properly initializes
request_itemsif it'sNone - 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:
- Atomicity: All request items are validated before any are added to prevent partial parsing
- NoneType safety: Initializes
request_itemsto[]ifNonebefore 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