diem/diem · error

Expected to parse struct tag, but got {}

Error message

Expected to parse struct tag, but got {}

What it means

After reading the file stem, view_resource parses it as a Move TypeTag and requires it to be a struct (TypeTag::Struct). A parsable but non-struct tag — e.g. a primitive like 'u64' or a vector — cannot identify a resource, so the error reports the actual parsed tag.

Source

Thrown at language/tools/move-cli/src/sandbox/utils/on_disk_state_view.rs:303

    /// Returns a deserialized representation of the resource value stored at `resource_path`.
    /// Returns Err if the path does not hold a resource value or the resource cannot be deserialized
    pub fn view_resource(&self, resource_path: &Path) -> Result<Option<AnnotatedMoveStruct>> {
        if resource_path.is_dir() {
            bail!(
                "Bad resource path {:?}. Needed file, found directory",
                resource_path
            )
        }
        match resource_path.file_stem() {
            None => bail!(
                "Bad resource path {:?}; last component must be a file",
                resource_path
            ),
            Some(name) => Ok({
                let id = match parser::parse_type_tag(&name.to_string_lossy())? {
                    TypeTag::Struct(s) => s,
                    t => bail!("Expected to parse struct tag, but got {}", t),
                };
                match Self::get_bytes(resource_path)? {
                    Some(resource_data) => {
                        Some(MoveValueAnnotator::new(self).view_resource(&id, &resource_data)?)
                    }
                    None => None,
                }
            }),
        }
    }

    fn get_events(&self, events_path: &Path) -> Result<Vec<Event>> {
        Ok(if events_path.exists() {
            match Self::get_bytes(events_path)? {
                Some(events_data) => bcs::from_bytes::<Vec<Event>>(&events_data)?,
                None => vec![],
            }
        } else {

View on GitHub (pinned to fc4714a8ea)

Solutions

  1. Rename/point to a file whose stem is a full struct type tag: <address>::<module>::<Struct><type args>.
  2. Verify the path targets a file produced by the sandbox resource dump, not an arbitrary file.
  3. Check the tag for dropped generic arguments or module path segments that change parsing.

Example fix

// before
move view --resource-path ./state/0x42/resources/u64.bcs
// after
move view --resource-path ./state/0x42/resources/0x1::coin::CoinStore<0x42>.bcs
Defensive patterns

Strategy: validation

Validate before calling

use move_core_types::language_storage::TypeTag;
use move_core_types::parser;
fn parse_struct_tag_name(name: &str) -> Option<String> {
    match parser::parse_type_tag(name) {
        Ok(TypeTag::Struct(_)) => Some(name.to_string()),
        _ => None,
    }
}

Type guard

fn is_struct_tag(s: &str) -> bool {
    matches!(move_core_types::parser::parse_type_tag(s), Ok(move_core_types::language_storage::TypeTag::Struct(_)))
}

Try / catch

match parser::parse_type_tag(name) {
    Ok(TypeTag::Struct(s)) => view(s),
    Ok(other) => eprintln!("{} is not a struct tag", other),
    Err(e) => eprintln!("unparseable tag: {}", e),
}

Prevention

When it happens

Trigger: The resource file's name parses as a valid type tag but is not a struct: files named like 'u64.bcs', 'vector<u8>.bcs', 'address.bcs', or a signer type instead of a struct type such as 0x1::coin::CoinStore<...>.

Common situations: Renaming resource files manually; copy scripts that mangle struct tags; pointing view at bytecode or non-resource files whose names happen to be type tags.

Related errors


AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04). Data as JSON: /api/errors/12e6d44a4017bfe8. Report an issue: GitHub.