helix-editor/helix · error · anyhow::Error

invalid language id: {}

Error message

invalid language id: {}

What it means

Document::set_language_by_language_id looks the name up via Loader::language_for_name, which searches the languages loaded from languages.toml (and user overrides). An id that matches no configured language returns None and the method fails with "invalid language id: {id}". Note this resolves by language name, not file extension or scope.

Source

Thrown at helix-view/src/document.rs:1389

                    // been logged by `LanguageData::syntax_config`.
                    if err != syntax::HighlighterError::NoRootConfig {
                        log::warn!("Error building syntax for '{}': {err}", self.display_name());
                    }
                })
                .ok()
        });
    }

    /// Set the programming language for the file if you know the language but don't have the
    /// [`syntax::config::LanguageConfiguration`] for it.
    pub fn set_language_by_language_id(
        &mut self,
        language_id: &str,
        loader: &syntax::Loader,
    ) -> anyhow::Result<()> {
        let language = loader
            .language_for_name(language_id)
            .ok_or_else(|| anyhow!("invalid language id: {}", language_id))?;
        let config = loader.language(language).config().clone();
        self.set_language(Some(config), loader);
        Ok(())
    }

    /// Select text within the [`Document`].
    pub fn set_selection(&mut self, view_id: ViewId, selection: Selection) {
        // TODO: use a transaction?
        self.selections
            .insert(view_id, selection.ensure_invariants(self.text().slice(..)));
        helix_event::dispatch(SelectionDidChange {
            doc: self,
            view: view_id,
        })
    }

    /// Find the origin selection of the text in a document, i.e. where
    /// a single cursor would go if it were on the first grapheme. If

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Use the exact language name from languages.toml, e.g. :set-language-id typescript rather than "ts" or "TSX".
  2. If it is a custom language, verify the languages.toml/user-languages.toml entry parses (run :config-reload or check :log-open for TOML errors).
  3. For API callers, check loader.language_for_name(id).is_some() before calling set_language_by_language_id and surface the list of valid names.

Example fix

// before
 doc.set_language_by_language_id("ts", loader)?; // Err: invalid language id: ts

// after
 doc.set_language_by_language_id("typescript", loader)?;
Defensive patterns

Strategy: validation

Validate before calling

let known = loader.language_for_name(language_id).is_some();
if !known {
    return Err(anyhow!(
        "language '{language_id}' not in languages.toml; known: e.g. rust, typescript, python"
    ));
}
doc.set_language_by_language_id(language_id, loader)?;

Type guard

fn known_language<'a>(loader: &'a syntax::Loader, id: &str) -> Option<&'a helix_core::syntax::Language> {
    loader.language_for_name(id)
}

Try / catch

match doc.set_language_by_language_id(id, loader) {
    Ok(()) => {}
    Err(err) if err.to_string().starts_with("invalid language id") => {
        // fall back to leaving the current language, tell the user which names exist
        editor.set_error(format!("{err}; check names in languages.toml"));
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Calling :set-language-id with a name absent from languages.toml; an LSP integration passing a languageId string that does not match a configured language name; a custom language defined in user config that failed to load due to a TOML error, so the name never registered.

Common situations: Typos or wrong casing when switching languages manually; upstream languages.toml renames in newer Helix versions; expecting a file-type extension ("rs", "ts") to work where the language name ("rust", "typescript") is required; user-languages.toml syntax errors silently removing custom entries.

Related errors


AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16). Data as JSON: /api/errors/6e8d9c514374e806. Report an issue: GitHub.