Bug description
404 - {"timestamp":1739777658784,"status":404,"error":"Not Found","path":"//v1/chat/completions"}
Environment
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
Steps to reproduce set application.yml
openai:
base-url: https://api.chatanywhere.tech/v1
run the program
@GetMapping("/ai/generate")
public Map<String,String> generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", this.chatModel.call(message));
}
Expected behavior a right response
Error
404 - {"timestamp":1739777658784,"status":404,"error":"Not Found","path":"//v1/chat/completions"}
Problem Explanation
I encountered an issue while trying to solve a problem with the OpenAI API integration. After some investigation, I found that the problem stems from the method internalCall() in the OpenAiChatModel class, and the method chatCompletionEntity() in OpenAiApi.
The root cause is that the uri() method used in the chatCompletionEntity() does not handle the removal of redundant slashes correctly. Specifically, the method does not remove the /v1 portion of the URL when constructing the final URI. As a result, it leads to an incorrect path: //v1/chat/completions, which triggers the 404 Not Found error.
Code Snippet
return ((RestClient.RequestBodySpec)((RestClient.RequestBodySpec)this.restClient.post().uri(this.completionsPath, new Object[0]))
.headers((headers) -> headers.addAll(additionalHttpHeader)))
.body(chatRequest)
.retrieve()
.toEntity(ChatCompletion.class);
Investigation and Next Steps
- The key issue is how the
uri()method constructs the URI. It leaves an extra slash (/) at the beginning of the path, resulting in an invalid endpoint (//v1/chat/completions). - I need to understand how the URI is being constructed and how to properly allocate the correct path. Specifically, I am wondering how to modify this logic to ensure that redundant slashes are removed, and the correct endpoint is used.
Solution Consideration
To resolve this, I may need to ensure that the base path and the completionsPath are combined correctly, removing any extra slashes in the process. I could modify the logic in the uri() method or handle the path manipulation before it is passed to the RestClient.
Comment From: dev-jonghoonpark
What happens if I remove the /v1 part of the openai.base-url in application.yml?
Is there any reason to add the /v1 part?
Comment From: apappascs
Please remove the versioning from the base url https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html
| Property | Description | Default |
|---|---|---|
| spring.ai.openai.chat.enabled | Enable OpenAI chat model. | true |
| spring.ai.openai.chat.base-url | Optional override for the spring.ai.openai.base-url property to provide a chat-specific URL. | - |
| spring.ai.openai.chat.completions-path | The path to append to the base URL. | /v1/chat/completions |
Comment From: colommar
What happens if I remove the
/v1part of the openai.base-url in application.yml? Is there any reason to add the/v1part?
It works cause there is a completionsPath = "/v1/chat/completions" which will be added after the base url. The reason why I think it can be added because the openai in python can solve this situation.
Comment From: apappascs
Thanks for confirming, @colommar. I think the issue can be closed if there’s nothing else.