rtk-ai/rtk · warning
{} — invalid TOML, not loaded: {}
Error message
{} — invalid TOML, not loaded: {} What it means
`rtk trust` (src/hooks/trust.rs:241) scans gated filter files — project `.rtk/filters.toml` and the global config-dir filters TOML (src/hooks/trust.rs:206-216) — parses each with `toml::from_str::<TomlFilterFile>` via `filter_parse_error` (src/core/toml_filter.rs:415), and prints `" {path} — invalid TOML, not loaded: {err}"` to stderr when parsing fails. This is a warning, not a thrown error: the file is skipped (`continue`) with `had_error = true`, and the trust run proceeds with remaining files. The `{err}` is the `toml` crate's message and includes line/column and the expected-vs-found detail, so the text after the colon is the actual diagnostic to act on. The same parse gate protects `rtk` startup, so a file flagged here is inert everywhere until fixed.
Source
Thrown at src/hooks/trust.rs:273
return Ok(());
}
let interactive = std::io::IsTerminal::is_terminal(&std::io::stdin());
let mut found_any = false;
let mut enabled_any = false;
let mut had_error = false;
for (scope, filter_path) in gated_filter_paths_labeled() {
if !filter_path.exists() {
continue;
}
let bytes = std::fs::read(&filter_path)
.with_context(|| format!("Failed to read {}", filter_path.display()))?;
let content = String::from_utf8_lossy(&bytes);
if let Some(err) = crate::core::toml_filter::filter_parse_error(&content) {
had_error = true;
eprintln!(
" {} — invalid TOML, not loaded: {}",
filter_path.display(),
err
);
continue;
}
let filters = crate::core::toml_filter::active_filter_summaries(&content);
if filters.is_empty() {
continue;
}
found_any = true;
if matches!(
check_trust(&filter_path).unwrap_or(TrustStatus::Untrusted),
TrustStatus::Trusted | TrustStatus::EnvOverride
) {
eprintln!(" {} already trusted.", filter_path.display());
enabled_any = true;
continue;View on GitHub (pinned to 29f9bb7161)
Solutions
- Run `rtk trust` and read the segment after `not loaded:` — the toml error gives the exact line/column (e.g. `expected `.`, `=`... at line 4 column 12`); open the named file at that position and fix the syntax (quote string values, close brackets/quotes, remove duplicate keys).
- Check for non-syntax damage: merge-conflict markers (`<<<<<<<`), BOM at file start, and CRLF line endings (`file .rtk/filters.toml` or `cat -A`); strip them (`dos2unix`, resolve the merge) since each produces confusing parse positions.
- Validate the file out-of-band before re-running: `python3 -c 'import tomllib;print(tomllib.load(open(".rtk/filters.toml","rb")))'` or any TOML linter (taplo, `taplo fmt --check`) — syntax-valid but schema-wrong files need checking keys against the current rtk filters documentation (`rtk trust` output lists the active filter summaries it expects).
- If the file was schema-valid on an older rtk, check the CHANGELOG/release notes for renamed filter keys, migrate the entries, then re-run `rtk trust` and confirm the file appears with its sha256 and trust prompt instead of the warning.
Example fix
# before — .rtk/filters.toml (line 4 has an unquoted regex → invalid TOML, not loaded: expected `.`, `=` ... [filter.cargo-build] command = "cargo build" pattern = ^warning: unused# missing quotes, `#` not a comment here # after [filter.cargo-build] command = "cargo build" pattern = "^warning: unused"
Defensive patterns
Strategy: validation
Validate before calling
# Before running `rtk trust`, syntax-check the gated files yourself:
python3 - <<'EOF'
import tomllib, pathlib
for p in [pathlib.Path(".rtk/filters.toml"),
pathlib.Path.home()/".config"/"rtk"/"filters.toml"]:
if p.exists():
try:
tomllib.load(open(p, "rb"))
print(f"OK {p}")
except Exception as e:
print(f"FAIL {p}: {e}")
EOF
# Or: taplo lint .rtk/filters.toml Try / catch
// In Rust tooling that writes filters.toml, validate round-trip before persisting:
fn validate_filters_toml(content: &str) -> Result<(), toml::de::Error> {
toml::from_str::<TomlFilterFile>(content).map(|_| ())
}
// Write only after validation succeeds (atomic write, no partial file):
// validate_filters_toml(&new_content)?; std::fs::write(&path, new_content)?; Prevention
- Quote every string value in filters.toml (patterns and globs especially — `^warn:`, `**/*.rs`, and values containing `#` or spaces must be quoted).
- After any merge that touches .rtk/filters.toml, grep for conflict markers (`<<<<<<<`, `>>>>>>>`) and run `rtk trust` as a gate — it reports the first bad line with line/column.
- Prefer LF line endings and no BOM (configure .gitattributes `*.toml text eol=lf`); BOM/CRLF from Windows editors are recurring causes of first-line parse errors.
- When upgrading rtk, re-run `rtk trust` immediately; a schema change (renamed/retyped keys) shows up here as a deserialization error with the offending key named, before you depend on the filters.
When it happens
Trigger: Running `rtk trust` (or `rtk trust --yes`) when `.rtk/filters.toml` or `~/.config/<data-dir>/filters.toml` contains TOML the `toml` crate rejects: syntax errors such as a missing closing quote or bracket, `key = value` with an unquoted string value, duplicate keys in one table, invalid inline-table/array syntax, or a wrong value type for a field of `TomlFilterFile`. Also triggered by leftover git merge-conflict markers (`<<<<<<<`/`>>>>>>>`), a UTF-8 BOM, or CRLF injected by a Windows editor — all surface as parse errors with a line number.
Common situations: Hand-editing `.rtk/filters.toml` to add a command filter and forgetting quotes around a glob/regex value; a teammate committing a filters file with smart quotes pasted from docs or chat; a botched merge leaving conflict markers; generating the file on Windows with CRLF; upgrading rtk to a version whose `TomlFilterFile` schema changed (renamed/retyped keys) so previously-valid TOML now fails deserialization. Users notice filters silently not applying, then see this line when running `rtk trust`.
AI-assisted analysis of rtk-ai/rtk@29f9bb7161 (2026-08-20).
Data as JSON: /api/errors/7d75dcc59c44926c.
Report an issue: GitHub.