vectordotdev/vector · error

Failed to get extension for

Error message

Failed to get extension for: {input_path:?}

What it means

convert_config determines the input format from the input file's extension. If the path has no extension, Option::unwrap_or_else panics with 'Failed to get extension for: <path>'. Only files whose extension maps to a known Format (yaml/json/toml) are converted; others are skipped gracefully.

Solutions

  1. Rename the input file to include a supported extension (.yaml, .yml, .json, .toml)
  2. Pass a copy of the file with the correct extension if the original must keep its name
  3. Handle the case upstream: only call convert_config on paths where Path::extension().is_some()
  4. Patch to return an Err(Vec<String>) for extension-less files instead of panicking

Example fix

// before
.unwrap_or_else(|| panic!("Failed to get extension for: {input_path:?}"))
// after
match input_path.extension() {
    Some(ext) => ext,
    None => return Err(vec![format!("Input path {input_path:?} has no extension")]),
}
Defensive patterns

Strategy: validation

Validate before calling

fn has_known_ext(p: &std::path::Path) -> bool {
    matches!(p.extension().and_then(|e| e.to_str()), Some("yaml" | "yml" | "json" | "toml"))
}

Type guard

fn ext_of(p: &std::path::Path) -> Option<String> { p.extension()?.to_str().map(|s| s.to_string()) }

Prevention

When it happens

Trigger: Calling convert_config with an input path lacking an extension (e.g. 'config' instead of 'config.yaml'), or a path ending in a dot or a hidden dotfile like '.yaml' whose extension() is Some but unusual — the panic case is strictly extension() == None.

Common situations: Config files named without extensions (e.g. 'vector'), paths that are directories passed by mistake, or paths copied from URLs after stripping the extension.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/d660376c3e7ea744. Report an issue: GitHub.

Appendix: source

Thrown at src/convert_config.rs:117

                }
                exitcode::SOFTWARE
            }
        }
    }
}

fn convert_config(
    input_path: &Path,
    output_path: &Path,
    output_format: Format,
) -> Result<(), Vec<String>> {
    if output_path.exists() {
        return Err(vec![format!("Output path {output_path:?} exists")]);
    }
    let input_format = match Format::from_str(
        input_path
            .extension()
            .unwrap_or_else(|| panic!("Failed to get extension for: {input_path:?}"))
            .to_str()
            .unwrap_or_else(|| panic!("Failed to convert OsStr to &str for: {input_path:?}")),
    ) {
        Ok(format) => format,
        Err(_) => return Ok(()), // skip irrelevant files
    };

    if input_format == output_format {
        return Ok(());
    }

    #[allow(clippy::print_stdout)]
    {
        println!("Converting {input_path:?} config to {output_format:?}.");
    }
    let file_contents = fs::read_to_string(input_path).map_err(|e| vec![e.to_string()])?;
    let builder: ConfigBuilder = format::deserialize(&file_contents, input_format)?;
    let config = builder.build()?;

View on GitHub (pinned to bdb87aeaa4)