astrid-runtime/astrid · error

source.as_str()

Error message

source.as_str()

What it means

rename_region validates the source region exists and returns io::ErrorKind::NotFound with the source name when it is absent from state.regions. A rename needs actual region state (extents, length) to move; renaming a nonexistent source is rejected before the Rename journal record is appended.

Solutions

  1. Confirm the source region exists before renaming; after a successful rename, only the destination name remains valid.
  2. Make retry logic idempotent: if the destination exists and the source does not, treat the rename as already done.
  3. Use the exact region name string as created (watch case, extensions, path prefixes).
  4. Match on io::ErrorKind::NotFound to return a clear 'source region not found' error.

Example fix

// before
volume.rename_region(&src, &dst)?; // fails on retry
// after
if !volume.region_exists(&src) && volume.region_exists(&dst) {
    return Ok(()); // rename already applied
}
volume.rename_region(&src, &dst)?;
Defensive patterns

Strategy: validation

Validate before calling

if !region_exists(&volume, &src) {
    if region_exists(&volume, &dst) { return Ok(()); } // already renamed
    return Err(format!("source region {} not found", src.as_str()).into());
}
volume.rename_region(&src, &dst)?;

Type guard

fn renameable(src: &VolumeRegion, dst: &VolumeRegion, existing: &[String]) -> bool {
    existing.iter().any(|r| r == src.as_str()) && !existing.iter().any(|r| r == dst.as_str())
}

Try / catch

match volume.rename_region(&src, &dst) {
    Err(e) if e.kind() == io::ErrorKind::NotFound => eprintln!("source {} missing", src.as_str()),
    Err(e) if e.kind() == io::ErrorKind::AlreadyExists => eprintln!("destination {} taken", dst.as_str()),
    r => r?,
}

Prevention

When it happens

Trigger: Calling rename_region with a source &VolumeRegion never created, already removed, already renamed away (source no longer exists after a prior successful rename), or with a name differing in case/whitespace from the created one.

Common situations: Retrying a rename whose first attempt succeeded (source is now the destination name); renaming regions across separate volume instances; region-name constants drifting between modules.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/6307f7115190075c. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-storage/src/volume/hosted/mod.rs:341

        let mut state = self.state.lock();
        if !state.regions.contains_key(region) {
            return Err(io::Error::new(io::ErrorKind::NotFound, region.as_str()));
        }
        Self::append(&mut state, Operation::Remove, region, 0, &[])?;
        state.regions.remove(region);
        Ok(())
    }

    fn rename_region(&self, source: &VolumeRegion, destination: &VolumeRegion) -> io::Result<()> {
        let mut state = self.state.lock();
        if state.regions.contains_key(destination) {
            return Err(io::Error::new(
                io::ErrorKind::AlreadyExists,
                destination.as_str(),
            ));
        }
        if !state.regions.contains_key(source) {
            return Err(io::Error::new(io::ErrorKind::NotFound, source.as_str()));
        }
        Self::append(
            &mut state,
            Operation::Rename,
            source,
            0,
            destination.as_str().as_bytes(),
        )?;
        let source_state = state
            .regions
            .remove(source)
            .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, source.as_str()))?;
        state.regions.insert(destination.clone(), source_state);
        Ok(())
    }

    fn replace_region(&self, source: &VolumeRegion, destination: &VolumeRegion) -> io::Result<()> {
        let mut state = self.state.lock();

View on GitHub (pinned to affd8760f4)