fix(rag): fail loudly when a RAG's vault secret is missing
`interpolate_secrets` does not error on a secret the vault cannot resolve: it substitutes the empty string and returns the name in its second tuple element. `load_async` discarded that vec, so a typo'd or deleted vault secret produced `api_key = ""` and an unexplained 401 from Qdrant. Bail instead, naming the RAG and the missing secrets, matching what global config loading already does.
This commit is contained in:
+14
-2
@@ -377,10 +377,22 @@ impl Rag {
|
|||||||
|
|
||||||
let api_key: Option<String> = match data.driver_config.get("api_key") {
|
let api_key: Option<String> = match data.driver_config.get("api_key") {
|
||||||
Some(placeholder) => {
|
Some(placeholder) => {
|
||||||
let (resolved, _) =
|
let (resolved, missing) = interpolate_secrets(placeholder, vault)
|
||||||
interpolate_secrets(placeholder, vault).with_context(|| {
|
.with_context(|| {
|
||||||
format!("Failed to resolve api_key secret for RAG '{name}'")
|
format!("Failed to resolve api_key secret for RAG '{name}'")
|
||||||
})?;
|
})?;
|
||||||
|
// A secret the vault does not hold is NOT an error inside
|
||||||
|
// `interpolate_secrets`: it substitutes an empty string and
|
||||||
|
// only reports the name. Accepting that silently attaches with
|
||||||
|
// `api_key = ""`, and the user sees an unexplained 401 from the
|
||||||
|
// server instead of the typo they made.
|
||||||
|
if !missing.is_empty() {
|
||||||
|
bail!(
|
||||||
|
"RAG '{name}' references secrets that are missing from the vault: {}. \
|
||||||
|
Add them with `coyote --add-secret <name>`, then try again.",
|
||||||
|
missing.join(", ")
|
||||||
|
);
|
||||||
|
}
|
||||||
Some(resolved)
|
Some(resolved)
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
|
|||||||
Reference in New Issue
Block a user