astrid-runtime/astrid · error

redirect fixture

Error message

redirect fixture

What it means

The message "redirect fixture" is the expect() on std::os::unix::fs::symlink(&outside, principal_home.audit_dir().join("redirect")) at audit_retirement_tests.rs:35-36. This plants a symlink named 'redirect' inside the principal's audit directory pointing outside the tree — the exact pattern retire_legacy_audit_dir must reject. The expect panics if symlink creation fails; the function is unix-only (the test is cfg(unix)) and fails on filesystems or platforms that disallow symlinks, or if audit_dir does not exist.

Source

Thrown at crates/astrid-kernel/src/audit_retirement_tests.rs:36

        !home
            .migrations_dir()
            .join("audit-principal-home.retired")
            .exists()
    );
}

#[cfg(unix)]
#[test]
fn audit_retirement_rejects_redirects_before_removal() {
    let directory = tempfile::tempdir().expect("temporary home");
    let home = AstridHome::from_path(directory.path().join(".astrid"));
    home.ensure().expect("home layout");
    let principal_home = home.principal_home(&astrid_core::PrincipalId::default());
    principal_home.ensure().expect("legacy principal layout");
    let outside = directory.path().join("outside");
    std::fs::create_dir(&outside).expect("outside fixture");
    std::os::unix::fs::symlink(&outside, principal_home.audit_dir().join("redirect"))
        .expect("redirect fixture");

    assert!(retire_legacy_audit_dir(&home, &principal_home.audit_dir()).is_err());
    assert!(principal_home.audit_dir().exists());
}

#[test]
fn derived_audit_recertify_helper_rejects_invalid_history() {
    let valid = vec![(
        SessionId::new(),
        ChainVerificationResult {
            valid: true,
            entries_verified: 1,
            issues: Vec::new(),
        },
    )];
    require_audit_integrity(&valid).expect("valid history is accepted by the derived helper");

    let invalid = vec![(

View on GitHub (pinned to affd8760f4)

Solutions

  1. Confirm principal_home.ensure() ran and created audit_dir before line 35.
  2. Check no prior run left a 'redirect' entry in the audit dir; tempdirs should be unique, so prefer fixing a shared-path bug over deleting manually.
  3. Run on a native unix filesystem with symlink support (ext4/apfs); avoid network mounts for cargo test target dirs.
  4. Since retire_legacy_audit_dir must reject this symlink, keep the fixture; only change creation mechanics, not the semantics.

Example fix

// before
std::os::unix::fs::symlink(&outside, principal_home.audit_dir().join("redirect"))
    .expect("redirect fixture");
// after
let link = principal_home.audit_dir().join("redirect");
std::os::unix::fs::symlink(&outside, &link)
    .unwrap_or_else(|e| panic!("redirect fixture: symlink {} -> {}: {e}", link.display(), outside.display()));
Defensive patterns

Strategy: validation

Validate before calling

let link = principal_home.audit_dir().join("redirect");
if link.symlink_metadata().is_ok() {
    panic!("redirect fixture: {} already exists", link.display());
}
if !principal_home.audit_dir().is_dir() {
    panic!("redirect fixture: audit dir missing");
}

Type guard

fn symlinks_supported(dir: &std::path::Path) -> bool {
    let probe = dir.join(".symlink-probe");
    match std::os::unix::fs::symlink("target", &probe) {
        Ok(_) => { std::fs::remove_file(&probe).ok(); true }
        Err(_) => false,
    }
}

Try / catch

std::os::unix::fs::symlink(&outside, &link)
    .unwrap_or_else(|e| panic!("redirect fixture: {} -> {}: {e}", link.display(), outside.display()));

Prevention

When it happens

Trigger: symlink() returns Err: audit_dir was never created by ensure(), a file/symlink named 'redirect' already exists (AlreadyExists), the filesystem is Windows/NTFS or a mount with symlinks disabled (EPERM), or permissions block inode creation in audit_dir.

Common situations: Running the unix-gated test on filesystems without symlink support (FAT/exFAT mounts, some Windows Developer-mode setups if cfg(unix) were removed); running tests as a user without symlink privileges; ensure() regressions leaving audit_dir absent.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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