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
/v1
part of the openai.base-url in application.yml? Is there any reason to add the/v1
part?
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.