#1140·gpt-pilot

[Bug]: JSONDecodeError: Extra data: line 2 column 1 (char 1855) raised by openai api when preprocess_response function for llm model response is pursued (gpt4-o model) in langgraph application

Author: sopfiCreated Feb 16, 2025Updated Jun 27, 2025
Labelsbug

Version

VisualStudio Code extension

Operating System

Windows 10

What happened?

The following traceback is generated when calling the gpt4-o model via the Azure OpenAI API:


JSONDecodeError Traceback (most recent call last)

in <cell line: 0>() 107 #code_interpreter.upload_file("/content/BoostAndSlowCarSpeed.png") 108 #user input 7 easier, user input 21 more difficult --> 109 result = app.graph.invoke({ 110 "userrequest": userinput21, 111 "num_tries_action":0,

28 frames

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/init.py in invoke(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, debug, **kwargs) 2140 else: 2141 chunks = [] -> 2142 for chunk in self.stream( 2143 input, 2144 config,

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/init.py in stream(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, debug, subgraphs) 1795 # with channel updates applied only at the transition between steps. 1796 while loop.tick(input_keys=self.input_channels): -> 1797 for _ in runner.tick( 1798 loop.tasks.values(), 1799 timeout=self.step_timeout,

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/runner.py in tick(self, tasks, reraise, timeout, retry_policy, get_waiter) 228 t = tasks[0] 229 try: --> 230 run_with_retry( 231 t, 232 retry_policy,

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/retry.py in run_with_retry(task, retry_policy, configurable) 38 task.writes.clear() 39 # run the task ---> 40 return task.proc.invoke(task.input, config) 41 except ParentCommand as exc: 42 ns: str = config[CONF][CONFIG_KEY_CHECKPOINT_NS]

/usr/local/lib/python3.11/dist-packages/langgraph/utils/runnable.py in invoke(self, input, config, **kwargs) 544 ) 545 if i == 0: --> 546 input = step.invoke(input, config, **kwargs) 547 else: 548 input = step.invoke(input, config)

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/init.py in invoke(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, debug, **kwargs) 2140 else: 2141 chunks = [] -> 2142 for chunk in self.stream( 2143 input, 2144 config,

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/init.py in stream(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, debug, subgraphs) 1795 # with channel updates applied only at the transition between steps. 1796 while loop.tick(input_keys=self.input_channels): -> 1797 for _ in runner.tick( 1798 loop.tasks.values(), 1799 timeout=self.step_timeout,

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/runner.py in tick(self, tasks, reraise, timeout, retry_policy, get_waiter) 228 t = tasks[0] 229 try: --> 230 run_with_retry( 231 t, 232 retry_policy,

/usr/local/lib/python3.11/dist-packages/langgraph/pregel/retry.py in run_with_retry(task, retry_policy, configurable) 38 task.writes.clear() 39 # run the task ---> 40 return task.proc.invoke(task.input, config) 41 except ParentCommand as exc: 42 ns: str = config[CONF][CONFIG_KEY_CHECKPOINT_NS]

/usr/local/lib/python3.11/dist-packages/langgraph/utils/runnable.py in invoke(self, input, config, **kwargs) 544 ) 545 if i == 0: --> 546 input = step.invoke(input, config, **kwargs) 547 else: 548 input = step.invoke(input, config)

/usr/local/lib/python3.11/dist-packages/langgraph/utils/runnable.py in invoke(self, input, config, **kwargs) 308 else: 309 context.run(_set_config_context, config) --> 310 ret = context.run(self.func, *args, **kwargs) 311 if isinstance(ret, Runnable) and self.recurse: 312 return ret.invoke(input, config)

in generate_code(self, state) 268 messages = [SystemMessage(content=system_prompt_for_actionexecutor.format(user_request=state['userrequest'],plan=state['plan_current_actions']))] + state['shortterm_memory_between_subtasks'] + state['shortterm_memory_within_subtasks'] #maybe add last three reflection elements as longterm memory or element from longterm memory determined with semantic search either as messages or prefered as context to the system prompt, maybe change shortterm memory from messages to context to the system prompt 269 print("Debug function generate_code, messages for model invokation: {}".format(messages)) --> 270 response=self.model_actionexecutor.invoke(messages) 271 print("Debug function generate_code, response after model invokation: {}".format(response)) 272 ai_msg_from_response = response

/usr/local/lib/python3.11/dist-packages/langchain_core/runnables/base.py in invoke(self, input, config, **kwargs) 5358 **kwargs: Optional[Any], 5359 ) -> Output: -> 5360 return self.bound.invoke( 5361 input, 5362 self._merge_configs(config),

/usr/local/lib/python3.11/dist-packages/langchain_core/language_models/chat_models.py in invoke(self, input, config, stop, **kwargs) 282 return cast( 283 ChatGeneration, --> 284 self.generate_prompt( 285 [self._convert_input(input)], 286 stop=stop,

/usr/local/lib/python3.11/dist-packages/langchain_core/language_models/chat_models.py in generate_prompt(self, prompts, stop, callbacks, **kwargs) 858 ) -> LLMResult: 859 prompt_messages = [p.to_messages() for p in prompts] --> 860 return self.generate(prompt_messages, stop=stop, callbacks=callbacks, **kwargs) 861 862 async def agenerate_prompt(

/usr/local/lib/python3.11/dist-packages/langchain_core/language_models/chat_models.py in generate(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs) 688 try: 689 results.append( --> 690 self._generate_with_cache( 691 m, 692 stop=stop,

/usr/local/lib/python3.11/dist-packages/langchain_core/language_models/chat_models.py in _generate_with_cache(self, messages, stop, run_manager, **kwargs) 923 else: 924 if inspect.signature(self._generate).parameters.get("run_manager"): --> 925 result = self._generate( 926 messages, stop=stop, run_manager=run_manager, **kwargs 927 )

/usr/local/lib/python3.11/dist-packages/langchain_openai/chat_models/base.py in _generate(self, messages, stop, run_manager, **kwargs) 781 generation_info = {"headers": dict(raw_response.headers)} 782 else: --> 783 response = self.client.create(**payload) 784 return self._create_chat_result(response, generation_info) 785

/usr/local/lib/python3.11/dist-packages/openai/_utils/_utils.py in wrapper(*args, **kwargs) 277 msg = f"Missing required argument: {quote(missing[0])}" 278 raise TypeError(msg) --> 279 return func(*args, **kwargs) 280 281 return wrapper # type: ignore

/usr/local/lib/python3.11/dist-packages/openai/resources/chat/completions.py in create(self, messages, model, audio, frequency_penalty, function_call, functions, logit_bias, logprobs, max_completion_tokens, max_tokens, metadata, modalities, n, parallel_tool_calls, prediction, presence_penalty, reasoning_effort, response_format, seed, service_tier, stop, store, stream, stream_options, temperature, tool_choice, tools, top_logprobs, top_p, user, extra_headers, extra_query, extra_body, timeout) 861 ) -> ChatCompletion | Stream[ChatCompletionChunk]: 862 validate_response_format(response_format) --> 863 return self._post( 864 "/chat/completions", 865 body=maybe_transform(

/usr/local/lib/python3.11/dist-packages/openai/_base_client.py in post(self, path, cast_to, body, options, files, stream, stream_cls) 1281 method="post", url=path, json_data=body, files=to_httpx_files(files), **options 1282 ) -> 1283 return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) 1284 1285 def patch(

/usr/local/lib/python3.11/dist-packages/openai/_base_client.py in request(self, cast_to, options, remaining_retries, stream, stream_cls) 958 retries_taken = 0 959 --> 960 return self._request( 961 cast_to=cast_to, 962 options=options,

/usr/local/lib/python3.11/dist-packages/openai/_base_client.py in _request(self, cast_to, options, retries_taken, stream, stream_cls) 1064 raise self._make_status_error_from_response(err.response) from None 1065 -> 1066 return self._process_response( 1067 cast_to=cast_to, 1068 options=options,

/usr/local/lib/python3.11/dist-packages/openai/_base_client.py in _process_response(self, cast_to, options, response, stream, stream_cls, retries_taken) 1163 return cast(ResponseT, api_response) 1164 -> 1165 return api_response.parse() 1166 1167 def _request_api_list(

/usr/local/lib/python3.11/dist-packages/openai/_response.py in parse(self, to) 321 self.read() 322 --> 323 parsed = self._parse(to=to) 324 if is_given(self._options.post_parser): 325 parsed = self._options.post_parser(parsed)

/usr/local/lib/python3.11/dist-packages/openai/_response.py in _parse(self, to) 263 return response.text # type: ignore 264 --> 265 data = response.json() 266 267 return self._client._process_response_data(

/usr/local/lib/python3.11/dist-packages/httpx/_models.py in json(self, **kwargs) 830 831 def json(self, **kwargs: typing.Any) -> typing.Any: --> 832 return jsonlib.loads(self.content, **kwargs) 833 834 @property

/usr/lib/python3.11/json/init.py in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) 344 parse_int is None and parse_float is None and 345 parse_constant is None and object_pairs_hook is None and not kw): --> 346 return _default_decoder.decode(s) 347 if cls is None: 348 cls = JSONDecoder

/usr/lib/python3.11/json/decoder.py in decode(self, s, _w) 338 end = _w(s, end).end() 339 if end != len(s): --> 340 raise JSONDecodeError("Extra data", s, end) 341 return obj 342

JSONDecodeError: Extra data: line 2 column 1 (char 1855)

It seems that some preprocessing_response function checks the llm model response to be valid json. The model response seems not to be valid json and then raises the error. How to fix this issue? Can I turn off the validation of the model response to be valid json or instead make the model produce valid json output. The response_format parameter can not be used because the paramter is unknown to the model.