rtk-ai/rtk · error
config.toml is not valid TOML
Error message
config.toml is not valid TOML: {e} What it means
apply_recall_mode parses the user's config.toml with toml_edit before rewriting the retriever/tee sections. If the file content is not syntactically valid TOML, the parse fails and the function wraps the toml_edit error in this anyhow error.
Solutions
- Open config.toml and fix the TOML syntax error reported after the colon (line/column are included by toml_edit).
- Validate the file with a TOML linter or `python -c "import tomllib;tomllib.load(open('config.toml','rb'))"`.
- If unsure, back up and delete/recreate config.toml, then re-run the command to regenerate defaults.
Example fix
// before (broken) retriever = sqlite tee = // after [retriever] mode = "sqlite"
Defensive patterns
Strategy: try-catch
Validate before calling
import tomllib
with open('config.toml','rb') as f:
tomllib.load(f) # raises on invalid TOML before running rtk Try / catch
match rtk_set_recall_mode(mode) {
Err(e) if e.to_string().contains("not valid TOML") => {
eprintln!("Fix config.toml first: {e}");
// open editor / restore backup
}
Err(e) => return Err(e),
Ok(_) => (),
} Prevention
- Validate config.toml with a TOML parser after every hand edit
- Keep a known-good backup of config.toml
- Use rtk commands instead of manual edits to change settings
When it happens
Trigger: Calling set_recall_mode (or the internal apply_recall_mode in tests) while ~/.config/rtk/config.toml (or the config content passed in) contains a TOML syntax error: unclosed string, duplicate key, missing bracket on a table header, stray tab, etc.
Common situations: Hand-edited config.toml with a typo; a previous crashed/partial write; pasting JSON into a TOML file; merging conflicting edits leaving duplicated keys.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Filter file present but not valid TOML — see the error…
- — invalid TOML, not loaded
- No custom filters found (.rtk/filters.toml or…
- filter(s) have no inline tests (use --require-all in CI)
- negative event length
AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19).
Data as JSON: /api/errors/53e72087b2f5abc6.
Report an issue: GitHub.
Appendix: source
Thrown at src/core/config.rs:395
}
let content = toml::to_string_pretty(self)?;
std::fs::write(&path, content)?;
Ok(())
}
pub fn create_default() -> Result<PathBuf> {
let config = Config::default();
config.save()?;
get_config_path()
}
}
fn apply_recall_mode(content: &str, mode: crate::core::retriever::RecoveryMode) -> Result<String> {
use crate::core::retriever::RecoveryMode;
let mut doc: toml_edit::DocumentMut = content
.parse()
.map_err(|e| anyhow::anyhow!("config.toml is not valid TOML: {e}"))?;
let legacy = doc.remove("tee");
let retriever_is_table = doc
.get("retriever")
.is_some_and(|item| item.as_table_like().is_some());
if !retriever_is_table {
doc["retriever"] = toml_edit::Item::Table(toml_edit::Table::new());
}
let mode_str = match mode {
RecoveryMode::Sqlite => "sqlite",
RecoveryMode::Tee => "tee",
RecoveryMode::Disabled => "disabled",
};
doc["retriever"]["mode"] = toml_edit::value(mode_str);
if let Some(legacy) = legacy.as_ref().and_then(|i| i.as_table_like()) {
let tee = LegacyTeeConfig {
enabled: legacyView on GitHub (pinned to 0924356b4c)