FuelLabs/sway · error · anyhow::Error
{:?}: could not read: {:?}
Error message
{:?}: could not read: {:?} What it means
forc addr2line's exec does fs::read(command.sourcemap_path) and on any io failure returns "<path>: could not read: <io error debug>". Unlike most errors here it preserves the underlying error (kind, message) in {:?} form, so NotFound vs PermissionDenied is visible in the output.
Source
Thrown at forc/src/cli/commands/addr2line.rs:34
#[derive(Debug, Parser)]
pub(crate) struct Command {
/// Where to search for the project root
#[clap(short = 'S', long, default_value = ".")]
pub search_dir: PathBuf,
/// Source file mapping in JSON format
#[clap(short = 'g', long)]
pub sourcemap_path: PathBuf,
/// How many lines of context to show
#[clap(short, long, default_value = "2")]
pub context: usize,
/// Opcode index
#[clap(short = 'i', long)]
pub opcode_index: usize,
}
pub(crate) fn exec(command: Command) -> ForcResult<()> {
let contents = fs::read(&command.sourcemap_path)
.map_err(|err| anyhow!("{:?}: could not read: {:?}", command.sourcemap_path, err))?;
let sm: SourceMap = serde_json::from_slice(&contents).map_err(|err| {
anyhow!(
"{:?}: invalid source map json: {}",
command.sourcemap_path,
err
)
})?;
if let Some((mut path, range)) = sm.addr_to_span(command.opcode_index) {
if path.is_relative() {
path = command.search_dir.join(path);
}
let rr = read_range(&path, range, command.context)
.map_err(|err| anyhow!("{:?}: could not read: {:?}", path, err))?;
let path_str = format!("{path:?}");View on GitHub (pinned to 47e5e902fa)
Solutions
- Regenerate the sourcemap: `forc build -g` (emits Forc.toml-adjacent sourcemap json for the binary) and pass that path with -g/--sourcemap-path
- Check the io error kind in the message: NotFound means wrong path, PermissionDenied means file mode problems
- Use an absolute path or run from the project root
Example fix
# before forc addr2line -g missing-map.json -i 42 # after forc build -g && forc addr2line -g out/debug/my_pkg.bin.json -i 42
Defensive patterns
Strategy: validation
Validate before calling
if !command.sourcemap_path.is_file() {
anyhow::bail!(
"sourcemap '{}' not found — build with `forc build -g` to generate it",
command.sourcemap_path.display()
);
} Try / catch
let contents = match std::fs::read(&sm_path) {
Ok(c) => c,
Err(e) => anyhow::bail!("cannot read sourcemap {}: {e} — regenerate with `forc build -g`", sm_path.display()),
}; Prevention
- Make `forc build -g` a prerequisite step in any addr2line workflow
- Pass absolute sourcemap paths, especially in CI
When it happens
Trigger: `forc addr2line -g <sourcemap.json> -i <pc>` where the sourcemap path does not exist, is unreadable, or the relative path does not resolve from the current working directory.
Common situations: Forgetting that the sourcemap is only emitted when building with the sourcemap flag, stale paths after clean/rename, or running addr2line from a different directory than assumed.
Related errors
- {:?}: invalid source map json: {}
- Source file was modified, and the mapping is now out of rang
- failed to read {}: {}
- invalid 'source' entry for package {} lock: {:?}
- failed to parse dependency "{}": {}
AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16).
Data as JSON: /api/errors/9968be03b9a3c738.
Report an issue: GitHub.