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

  1. 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).
  2. 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.
  3. 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).
  4. 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

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.