fix(backend): resolve relative draft_model paths against the models dir#9680
Merged
Conversation
The main model file and mmproj are joined with the configured models directory before reaching the backend, but draft_model was sent verbatim. With a relative draft_model in the YAML config, llama.cpp opens the path from the backend process's CWD and fails with "No such file or directory", forcing users to hard-code an absolute path. Mirror the existing mmproj resolution: if draft_model is relative, join it with modelPath. Absolute paths are passed through unchanged. Adds an e2e regression test against the mock backend that asserts the main model file, mmproj, and draft_model all arrive at the backend resolved to absolute paths. Closes #9675 Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-4-7-1m [Read] [Edit] [Bash] [Write]
…rtcut) The previous commit kept absolute draft_model paths intact via an IsAbs check. That left a path-traversal vector open: a user-supplied YAML config could set draft_model to /etc/passwd (or any other host file the backend process can read) and the path would be sent through unchanged. filepath.Join cleans the leading slash from absolute components, so joining unconditionally — the way mmproj already does — keeps the result rooted at the configured models directory regardless of input. Adds a second e2e spec that feeds an absolute draft_model into the mock backend and asserts the path is clamped under modelsPath. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-4-7-1m [Read] [Edit] [Bash]
mudler
approved these changes
May 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
draft_modelpaths against the configured models directory incore/backend/options.go, mirroring howparameters.modelandmmprojalready work. Without this, llama.cpp tries to open the path from the backend's CWD and fails withNo such file or directory, forcing users to hard-code an absolute path as a workaround.tests/e2e/path_resolution_test.go) that confirms the main model file,mmproj, anddraft_modelall arrive at the backend resolved to absolute paths.Why
Reported in #9675. The user's working
parameters.modeland brokendraft_modelhad identical relative-path syntax — the config looked symmetric, but only one side was resolved. Their workaround (/models/...absolute path) confirmed the diagnosis.The fix is one block in
grpcModelOpts:Test plan
go test -count=1 -run TestLocalAI ./tests/e2e/ -ginkgo.label-filter PathResolutionMockBackend-labelled specs still passThe mock backend gained a small instrumentation hook:
LoadModelrecords the incomingModelOptions, andPredictechoes them as JSON when the prompt containsECHO_LOAD_PARAMS. No new RPC, no test-only fields on the wire.Closes #9675