FuelLabs/sway · error

failed to read manifest at {:?}: {}

Error message

failed to read manifest at {:?}: {}

What it means

PackageManifestFile::from_file reads Forc.toml with fs::read_to_string and on failure reports the exact path and OS error. It covers missing files, permission errors, path-is-a-directory, and non-UTF-8 content; it is raised before any TOML parsing, so syntax problems surface later in from_string with different messages.

Source

Thrown at forc-pkg/src/manifest/mod.rs:669

impl PackageManifest {
    pub const DEFAULT_ENTRY_FILE_NAME: &'static str = "main.sw";

    /// Given a path to a `Forc.toml`, read it and construct a `PackageManifest`.
    ///
    /// This also `validate`s the manifest, returning an `Err` in the case that invalid names,
    /// fields were used.
    ///
    /// If `std` is unspecified, `std` will be added to the `dependencies` table
    /// implicitly. In this case, the git tag associated with the version of this crate is used to
    /// specify the pinned commit at which we fetch `std`.
    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
        // While creating a `ManifestFile` we need to check if the given path corresponds to a
        // package or a workspace. While doing so, we should be printing the warnings if the given
        // file parses so that we only see warnings for the correct type of manifest.
        let path = path.as_ref();
        let contents = std::fs::read_to_string(path)
            .map_err(|e| anyhow!("failed to read manifest at {:?}: {}", path, e))?;
        Self::from_string(contents)
    }

    /// Given a path to a `Forc.toml`, read it and construct a `PackageManifest`.
    ///
    /// This also `validate`s the manifest, returning an `Err` in the case that invalid names,
    /// fields were used.
    ///
    /// If `std` is unspecified, `std` will be added to the `dependencies` table
    /// implicitly. In this case, the git tag associated with the version of this crate is used to
    /// specify the pinned commit at which we fetch `std`.
    pub fn from_string(contents: String) -> Result<Self> {
        // While creating a `ManifestFile` we need to check if the given path corresponds to a
        // package or a workspace. While doing so, we should be printing the warnings if the given
        // file parses so that we only see warnings for the correct type of manifest.
        let mut warnings = vec![];
        let toml_de = toml::de::Deserializer::new(&contents);
        let mut manifest: Self = serde_ignored::deserialize(toml_de, |path| {

View on GitHub (pinned to 47e5e902fa)

Solutions

  1. Run the command from (or point --manifest-path at) the directory that actually contains Forc.toml.
  2. If starting a new project, create the manifest first with forc init.
  3. Ensure the file is UTF-8 encoded (no BOM/binary bytes) and readable by the current user.

Example fix

# before
$ cd packages/inner && forc build --manifest-path ./Forc.toml
error: failed to read manifest at "./Forc.toml" ...

# after
$ forc build --manifest-path ./packages/inner/Forc.toml  # path that exists
Defensive patterns

Strategy: validation

Validate before calling

// Rust, before PackageManifestFile::from_file:
use std::fs;
fn manifest_loadable(p: &std::path::Path) -> bool {
    fs::metadata(p).map(|m| m.is_file()).unwrap_or(false)
        && fs::read(p).map(|b| String::from_utf8(b).is_ok()).unwrap_or(false)
}

Try / catch

// anyhow Result - separate missing-file from other failures:
match PackageManifestFile::from_file(&path) {
    Ok(m) => m,
    Err(e) if e.to_string().contains("failed to read manifest") =>
        panic!("no readable Forc.toml at {} - run in the project root or pass --manifest-path", path.display()),
    Err(e) => panic!("manifest invalid: {e}"),
}

Prevention

When it happens

Trigger: Invoking forc (or any API that locates and loads a manifest - builds, forc add/remove, BuildPlan construction) where the Forc.toml path does not exist, is not a regular readable file, or is not valid UTF-8.

Common situations: Running forc build outside the project root; a wrong --manifest-path; CI checkouts that skipped the file; a manifest saved with a BOM or non-UTF-8 encoding by an editor; deleted or renamed manifest.

Related errors


AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16). Data as JSON: /api/errors/fda422e2d13556a7. Report an issue: GitHub.