[BUG] AI provider API key is not persisted correctly when editing provider
First Check
- This is not a feature request.
- I added a very descriptive title to this issue (title field is above this).
- I used the GitHub search to find a similar issue and didn't find it.
- I searched the Mealie documentation, with the integrated search.
- I already read the docs and didn't find an answer.
- This issue can be replicated on the demo site (https://demo.mealie.io/).
What is the issue you are experiencing?
When editing AI providers in Mealie, a newly entered API key was not persisted correctly in the database.
I use three Groq providers:
- Groq GPT-Oss
- Groq Vision
- Groq Whisper
All AI-assisted imports (image, PDF and URL imports using AI) started failing with:
400: Unable to read any content from the provided source
The Mealie server logs showed that the underlying error was actually:
401 Unauthorized - Invalid API Key
I generated a new Groq API key and entered it through the Mealie AI provider UI, but the problem remained.
I then tested the exact same new API key directly from the Mealie LXC against:
https://api.groq.com/openai/v1/models
and received HTTP 200.
Inspecting the PostgreSQL database showed that the new key entered through the UI had not been persisted correctly.
Before fixing it manually, the stored provider data looked like this:
Groq GPT-Oss: API key length 56, but still contained the previous key
Groq Whisper: API key length 56, but still contained the previous key
Groq Vision: API key length 1, containing only z
There were no custom provider headers or parameters and no Groq/OpenAI API-key environment variable configured.
After manually writing the valid API key into ai_providers.api_key for all three providers, all three stored keys returned HTTP 200 against Groq.
After restarting Mealie, image imports immediately worked again.
This strongly suggests that updating the API key through the AI provider UI does not always correctly persist the new value.
Steps to Reproduce
Configure an OpenAI-compatible AI provider in Mealie using Groq.
Use:
- Base URL: https://api.groq.com/openai/v1
- A valid Groq API key
Save the provider.
Edit the existing provider and enter a new valid API key.
Save/update the provider.
Try an AI-assisted recipe import, for example an image import.
The import fails with:
400: Unable to read any content from the provided sourceCheck the Mealie logs. The underlying request to Groq fails with:
401 Unauthorized - Invalid API KeyVerify the new API key independently from the same Mealie host:
GET https://api.groq.com/openai/v1/modelswith the new key returns HTTP 200.Inspect
ai_providers.api_keyin PostgreSQL.
In my case the newly entered key was not correctly persisted. One provider contained only a single character (z), while two other providers still contained the previous API key.
Manually update
ai_providers.api_keywith the valid API key and restart Mealie.The AI import works immediately.
Please provide relevant logs
Mealie logs while attempting an image import:
HTTP Request: POST https://api.groq.com/openai/v1/chat/completions "HTTP/1.1 401 Unauthorized"
openai.AuthenticationError: Error code: 401 - {
'error': {
'message': 'Invalid API Key',
'type': 'invalid_request_error',
'code': 'invalid_api_key'
}
}
Exception: OpenAI Request Failed. AuthenticationError:
Error code: 401 - Invalid API Key
mealie.services.recipe.import_workflow.exceptions.NoRecipeDataError:
Unable to read any content from the provided source
400 Bad Request "POST /api/recipes/create/image HTTP/1.1"
400 Bad Request "POST /api/recipes/create/image HTTP/1.1"
Database state before manual repair:
Groq GPT-Oss | openai/gpt-oss-120b | key length 56
Groq Vision | qwen/qwen3.8-27b | key length 1 | stored value: z
Groq Whisper | whisper-large-v3-turbo | key length 56
Testing the newly generated API key directly from the same Mealie LXC returned:
HTTP: 200
Testing the API keys actually stored by Mealie before the manual repair returned:
Groq GPT-Oss: HTTP 401
Groq Vision: HTTP 401
Groq Whisper: HTTP 401
After manually updating ai_providers.api_key with the valid API key:
Groq GPT-Oss: HTTP 200
Groq Vision: HTTP 200
Groq Whisper: HTTP 200
After restarting Mealie, the image import worked successfully.
### Mealie Version
3.25.1
### Deployment
Other (please specify below)
### Additional Deployment Details
LXC / bare-metal via community-scripts, Debian 13, PostgreSQLSource: mealie-recipes/mealie