janhq/jan · error · ServerError

Invalid argument

Error message

Invalid argument: {0}

What it means

ServerError::InvalidArgument is thrown when a command receives a parameter that fails validation, displayed as "Invalid argument: {0}" with a descriptive message. Unlike the #[from] variants it must be constructed explicitly, so it marks caller-supplied input problems rather than environmental failures. It is the plugin's contract-violation signal for IPC calls.

Solutions

  1. Read the embedded message; it names the offending parameter and the violated rule.
  2. Validate inputs on the frontend before invoking the command.
  3. Fix the calling code to send values matching the command's expected types and ranges.
  4. Check for recent signature changes between frontend invoke calls and Rust command definitions.

Example fix

// before: sending unvalidated input from the UI
invoke('start_server', { modelPath: userInput });
// after
if (!userInput || !userInput.endsWith('.gguf')) throw new Error('modelPath required');
invoke('start_server', { modelPath: userInput });
Defensive patterns

Strategy: validation

Validate before calling

function validateStartArgs(args) {
  if (!args.modelPath || typeof args.modelPath !== 'string' || !args.modelPath.endsWith('.gguf'))
    throw new Error('modelPath must be a .gguf file path');
  if (args.contextSize != null && (!Number.isInteger(args.contextSize) || args.contextSize <= 0))
    throw new Error('contextSize must be a positive integer');
}

Type guard

function isValidStartArgs(a) {
  return typeof a === 'object' && a !== null
    && typeof a.modelPath === 'string' && a.modelPath.length > 0;
}

Try / catch

try {
  await invoke('start_server', { modelPath });
} catch (msg) {
  if (String(msg).startsWith('Invalid argument:')) {
    showInputError(String(msg).slice('Invalid argument:'.length));
  } else { throw msg; }
}

Prevention

When it happens

Trigger: A #[tauri::command] validates its inputs (empty model name, malformed path, out-of-range port, negative context size) and returns ServerError::InvalidArgument(String) with the reason.

Common situations: Frontend sends an empty or null-ish model path, a bad temperature/seed value, or a path with unexpected characters; API changes leave the UI sending stale parameter shapes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/cae57aed2ae272c0. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/plugins/tauri-plugin-llamacpp/src/error.rs:205

    let candidate = candidate.trim_matches(['\'', '"', '(', ')', ',', '.'].as_ref());
    if looks_like_library(candidate) && !found.iter().any(|f| f == candidate) {
        found.push(candidate.to_string());
    }
}

// Error type for server commands
#[derive(Debug, thiserror::Error)]
pub enum ServerError {
    #[error(transparent)]
    Llamacpp(#[from] LlamacppError),

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    #[error("Tauri error: {0}")]
    Tauri(#[from] tauri::Error),

    #[error("Invalid argument: {0}")]
    InvalidArgument(String),
}

// impl serialization for tauri
impl serde::Serialize for ServerError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let error_to_serialize: LlamacppError = match self {
            ServerError::Llamacpp(err) => err.clone(),
            ServerError::Io(e) => LlamacppError::new(
                ErrorCode::IoError,
                "An input/output error occurred.".into(),
                Some(e.to_string()),
            ),
            ServerError::Tauri(e) => LlamacppError::new(
                ErrorCode::InternalError,

View on GitHub (pinned to 7205d770c1)