LocalAI version:
- current master (reproduced on a distributed deployment and patched in fork commit e0dc41d)
Environment, CPU architecture, OS, and Version:
- Reproduced against a LocalAI distributed deployment using model configs loaded from
/models
- Also reproduced directly from source in
core/config/ModelConfigLoader
Describe the bug
LoadModelConfigsFromPath() currently matches files using strings.Contains(file.Name(), ".yaml") / strings.Contains(file.Name(), ".yml").
Because of that, backup files like model.yaml.bak or model.yaml.bak.20260420 are also loaded as active model configs.
In practice this means stale backup configs can override the live config with the same name: and make /api/models/config-json/... and runtime behavior drift away from the actual model.yaml file.
To Reproduce
- Put these files in the models directory:
foo.yaml
foo.yaml.bak
foo.yaml.bak.123
- Give
foo.yaml and foo.yaml.bak the same name: but different description: or parser/template settings.
- Start LocalAI and load configs from that directory.
- Observe that the backup file is treated as a real config and can override the active one.
Minimal example:
foo.yaml => name: foo-model, description: formal config
foo.yaml.bak => name: foo-model, description: backup config
Expected behavior
Only files whose real extension is exactly .yaml or .yml should be loaded as configs. Backup files such as .yaml.bak or .yaml.bak.<timestamp> should be ignored.
Logs
No special runtime log is required to reproduce. The behavior is visible through loaded config state and API responses.
Additional context
I verified this in a live deployment by quarantining *.yaml.bak* files out of /models and restarting LocalAI. After that, /api/models/config-json/... and /api/models/edit/... immediately started returning the actual live config.
I also prepared a minimal fix and regression test in my fork:
- commit:
e0dc41d059b618afe7f6bc481dc88fa65b3f3be0
- branch:
codex/fix-model-config-loader-yaml-suffix
- fork branch URL:
https://github.com/leinasi2014/LocalAI/tree/codex/fix-model-config-loader-yaml-suffix
The fix changes the loader to check filepath.Ext(file.Name()) instead of substring matching, and the regression test verifies that:
foo.yaml is loaded
foo.yaml.bak is ignored
foo.yaml.bak.123 is ignored
- backup files do not override the active config
LocalAI version:
Environment, CPU architecture, OS, and Version:
/modelscore/config/ModelConfigLoaderDescribe the bug
LoadModelConfigsFromPath()currently matches files usingstrings.Contains(file.Name(), ".yaml")/strings.Contains(file.Name(), ".yml").Because of that, backup files like
model.yaml.bakormodel.yaml.bak.20260420are also loaded as active model configs.In practice this means stale backup configs can override the live config with the same
name:and make/api/models/config-json/...and runtime behavior drift away from the actualmodel.yamlfile.To Reproduce
foo.yamlfoo.yaml.bakfoo.yaml.bak.123foo.yamlandfoo.yaml.bakthe samename:but differentdescription:or parser/template settings.Minimal example:
foo.yaml=>name: foo-model,description: formal configfoo.yaml.bak=>name: foo-model,description: backup configExpected behavior
Only files whose real extension is exactly
.yamlor.ymlshould be loaded as configs. Backup files such as.yaml.bakor.yaml.bak.<timestamp>should be ignored.Logs
No special runtime log is required to reproduce. The behavior is visible through loaded config state and API responses.
Additional context
I verified this in a live deployment by quarantining
*.yaml.bak*files out of/modelsand restarting LocalAI. After that,/api/models/config-json/...and/api/models/edit/...immediately started returning the actual live config.I also prepared a minimal fix and regression test in my fork:
e0dc41d059b618afe7f6bc481dc88fa65b3f3be0codex/fix-model-config-loader-yaml-suffixhttps://github.com/leinasi2014/LocalAI/tree/codex/fix-model-config-loader-yaml-suffixThe fix changes the loader to check
filepath.Ext(file.Name())instead of substring matching, and the regression test verifies that:foo.yamlis loadedfoo.yaml.bakis ignoredfoo.yaml.bak.123is ignored