Skip to content

BadRequestError: 400 when using Free Groq/OpenAI compatible APIs due to max_completion_tokens mismatch #1236

@IvanPSG-BR

Description

@IvanPSG-BR

Server

  • Cloud (https://app.khoj.dev)
  • Self-Hosted Docker
  • Self-Hosted Python package
  • Self-Hosted source code

Clients

  • Web browser
  • Desktop/mobile app
  • Obsidian
  • Emacs
  • WhatsApp

OS

  • Windows
  • macOS
  • Linux
  • Android
  • iOS

Khoj version

2.0.0-b.22

Describe the bug

When using Groq as an OpenAI-compatible provider, chat requests fail with a BadRequestError: 400 for any model. The error message indicates that max_completion_tokens is either incorrectly set or not supported in the way it’s being passed.

Current Behavior

[02:46:02.469490] DEBUG uvicorn.error: > TEXT '{"error": protocol.py:1170
"Internal server error"}' [34 bytes]
[02:46:02.473333] ERROR khoj.routers.api_chat: Error api_chat.py:1699
processing chat request: Error code:
400 - {'error': {'message':
'max_completion_tokens must be
less than or equal to 8192, the
maximum value for
max_completion_tokens is less than
the context_window for this
model', 'type':
'invalid_request_error', 'param':
'max_completion_tokens'}}
╭─ Traceback (most recent call las─╮
│ /app/src/khoj/routers/api_chat.p │
│ y:1623 in process_chat_request │
│ │
│ 1620 │ │ │ websocket, │
│ 1621 │ │ │ interrupt_que │
│ 1622 │ │ ) │
│ ❱ 1623 │ │ async for event i │
│ 1624 │ │ │ if not event: │
│ 1625 │ │ │ │ continue │
│ 1626 │ │ │ elif event.st │
│ │
│ /app/src/khoj/routers/api_chat.p │
│ y:983 in event_generator │
│ │
│ 980 │ │
│ 981 │ if conversation_comma │
│ 982 │ │ try: │
│ ❱ 983 │ │ │ chosen_io = a │
│ 984 │ │ │ │ q, │
│ 985 │ │ │ │ chat_hist │
│ 986 │ │ │ │ user=user │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :414 in │
│ aget_data_sources_and_output_for │
│ mat │
│ │
│ 411 │ │ output: str │
│ 412 │ │
│ 413 │ with timer("Chat acto │
│ ❱ 414 │ │ raw_response = aw │
│ 415 │ │ │ relevant_tool │
│ 416 │ │ │ query_files=q │
│ 417 │ │ │ query_images= │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :1581 in │
│ send_message_to_model_wrapper │
│ │
│ 1578 │ │ ) │
│ 1579 │ │ │
│ 1580 │ │ try: │
│ ❱ 1581 │ │ │ return send_m │
│ 1582 │ │ │ │ chat_mode │
│ 1583 │ │ │ │ truncated │
│ 1584 │ │ │ │ response_ │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :1476 in send_message_to_model │
│ │
│ 1473 │ api_base_url = chat_m │
│ 1474 │ │
│ 1475 │ if model_type == Chat │
│ ❱ 1476 │ │ return openai_sen │
│ 1477 │ │ │ messages=trun │
│ 1478 │ │ │ api_key=api_k │
│ 1479 │ │ │ model=chat_mo │
│ │
│ /app/src/khoj/processor/conversa │
│ tion/openai/gpt.py:95 in │
│ openai_send_message_to_model │
│ │
│ 92 │ │ │ tracer=tracer, │
│ 93 │ │ ) │
│ 94 │ else: │
│ ❱ 95 │ │ return completion_ │
│ 96 │ │ │ messages=messa │
│ 97 │ │ │ model_name=mod │
│ 98 │ │ │ openai_api_key │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:338 │
│ in wrapped_f │
│ │
│ 335 │ │ │ # calling the │
│ 336 │ │ │ copy = self.co │
│ 337 │ │ │ wrapped_f.stat │
│ ❱ 338 │ │ │ return copy(f, │
│ 339 │ │ │
│ 340 │ │ def retry_with(*ar │
│ 341 │ │ │ return self.co │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:477 │
│ in call
│ │
│ 474 │ │ │
│ 475 │ │ retry_state = Retr │
│ 476 │ │ while True: │
│ ❱ 477 │ │ │ do = self.iter │
│ 478 │ │ │ if isinstance( │
│ 479 │ │ │ │ try: │
│ 480 │ │ │ │ │ result │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:378 │
│ in iter │
│ │
│ 375 │ │ self._begin_iter(r │
│ 376 │ │ result = None │
│ 377 │ │ for action in self │
│ ❱ 378 │ │ │ result = actio │
│ 379 │ │ return result │
│ 380 │ │
│ 381 │ def begin_iter(self, │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:400 │
│ in │
│ │
│ 397 │ │
│ 398 │ def post_retry_check
│ 399 │ │ if not (self.iter

│ ❱ 400 │ │ │ self._add_acti │
│ 401 │ │ │ return │
│ 402 │ │ │
│ 403 │ │ if self.after is n │
│ │
│ /usr/lib/python3.10/concurrent/f │
│ utures/_base.py:451 in result │
│ │
│ 448 │ │ │ │ if self._s │
│ 449 │ │ │ │ │ raise │
│ 450 │ │ │ │ elif self. │
│ ❱ 451 │ │ │ │ │ return │
│ 452 │ │ │ │ │
│ 453 │ │ │ │ self._cond │
│ 454 │
│ │
│ /usr/lib/python3.10/concurrent/f │
│ utures/_base.py:403 in │
│ __get_result │
│ │
│ 400 │ def __get_result(self) │
│ 401 │ │ if self.exception │
│ 402 │ │ │ try: │
│ ❱ 403 │ │ │ │ raise self │
│ 404 │ │ │ finally: │
│ 405 │ │ │ │ # Break a │
│ 406 │ │ │ │ self = Non │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:480 │
│ in call
│ │
│ 477 │ │ │ do = self.iter │
│ 478 │ │ │ if isinstance( │
│ 479 │ │ │ │ try: │
│ ❱ 480 │ │ │ │ │ result │
│ 481 │ │ │ │ except Bas │
│ 482 │ │ │ │ │ retry

│ 483 │ │ │ │ else: │
│ │
│ /app/src/khoj/processor/conversa │
│ tion/openai/utils.py:195 in │
│ completion_with_backoff │
│ │
│ 192 │ │ # if model_kwa │
│ 193 │ │ # model_kw │
│ 194 │ │ # --------------- │
│ ❱ 195 │ │ with client.beta. │
│ 196 │ │ │ messages=form │
│ 197 │ │ │ model=model_n │
│ 198 │ │ │ timeout=httpx │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/lib/streaming/cha │
│ t/_completions.py:150 in │
enter
│ │
│ 147 │ │ self.__input_tools │
│ 148 │ │
│ 149 │ def enter(self) -> │
│ ❱ 150 │ │ raw_stream = self. │
│ 151 │ │ │
│ 152 │ │ self.__stream = Ch │
│ 153 │ │ │ raw_stream=raw │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_utils/_utils.py: │
│ 286 in wrapper │
│ │
│ 283 │ │ │ │ │ else: │
│ 284 │ │ │ │ │ │ ms │
│ 285 │ │ │ │ raise Type │
│ ❱ 286 │ │ │ return func(*a │
│ 287 │ │ │
│ 288 │ │ return wrapper # │
│ 289 │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/resources/chat/co │
│ mpletions/completions.py:1192 in │
│ create │
│ │
│ 1189 │ │ timeout: float | │
│ 1190 │ ) -> ChatCompletion | │
│ 1191 │ │ validate_response │
│ ❱ 1192 │ │ return self._post │
│ 1193 │ │ │ "/chat/comple │
│ 1194 │ │ │ body=maybe_tr │
│ 1195 │ │ │ │ { │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_base_client.py:1 │
│ 259 in post │
│ │
│ 1256 │ │ opts = FinalReque │
│ 1257 │ │ │ method="post" │
│ **options │
│ 1258 │ │ ) │
│ ❱ 1259 │ │ return cast(Respo │
│ stream_cls=stream_cls)) │
│ 1260 │ │
│ 1261 │ def patch( │
│ 1262 │ │ self, │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_base_client.py:1 │
│ 047 in request │
│ │
│ 1044 │ │ │ │ │ err.r │
│ 1045 │ │ │ │ │
│ 1046 │ │ │ │ log.debug │
│ ❱ 1047 │ │ │ │ raise sel │
│ 1048 │ │ │ │
│ 1049 │ │ │ break │
│ 1050 │
╰──────────────────────────────────╯
BadRequestError: Error code: 400 -
{'error': {'message':
'max_completion_tokens must be
less than or equal to 8192, the
maximum value for
max_completion_tokens is less than
the context_window for this
model', 'type':
'invalid_request_error', 'param':
'max_completion_tokens'}}

Expected Behavior

The API models should reply without errors, returning 200 status code.

Reproduction Steps

  1. Configure Khoj to use Groq as an OpenAI-compatible chat provider.
  2. Attempt to start a chat session.
  3. Observe the 400 Bad Request error in the logs.

Possible Workaround

No response

Additional Information

No response

Link to Discord or Github discussion

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixFix something that isn't working as expected

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions