Skip to content

Restore-DbaDatabase -EnableException restores nothing with only a warning when no full backup anchors the chain #10621

Description

@andreasjordan

Summary

When Restore-DbaDatabase is given backup files that contain a differential or log backup but no full backup to anchor the chain, it warns and returns nothing - even with -EnableException, which promises "enables you to catch exceptions with your own try/catch". A caller that relies on the exception (for example a test fixture, or any script that restores and then works with the database) continues as if the restore had happened.

Repro (measured on SQL03\SQL2019, dbatools development)

$PSDefaultParameterValues["*-Dba*:EnableException"] = $true
# db restored from any full backup, then:
$full = Backup-DbaDatabase -SqlInstance $server -Database $db -Type Full -Path $dir -FilePath "full.bak"
$diff = Backup-DbaDatabase -SqlInstance $server -Database $db -Type Diff -Path $dir -FilePath "diff.bak"
$log  = Backup-DbaDatabase -SqlInstance $server -Database $db -Type Log  -Path $dir -FilePath "log.trn"

# no full in the set - warns, does not throw, returns nothing:
Restore-DbaDatabase -SqlInstance $server -Path $diff.BackupPath, $log.BackupPath -DatabaseName $db -WithReplace
# WARNING: [Select-DbaBackupInformation] Fullname property not found. This could mean that a full backup
# could not be found or the command must be re-run with the -Continue switch.

Mechanism

Select-DbaBackupInformation correctly calls Stop-Function when it cannot find a full backup (public/Select-DbaBackupInformation.ps1, the two "Fullname property not found" sites). But the splat that Restore-DbaDatabase builds for the call (public/Restore-DbaDatabase.ps1, around line 857) does not pass EnableException on, so inside Select-DbaBackupInformation the stop degrades to a warning, control returns, and Restore-DbaDatabase proceeds with an empty $FilteredBackupHistory to a successful-looking no-op.

Real-world impact

This is exactly how Get-DbaDbRestoreHistory.Tests.ps1 was flaky for years: its fixture restored diff+log without the full, which only worked because the default backup file name has minute resolution and the full and diff usually share one file. On a minute boundary the restore silently did nothing and six tests failed downstream (fixed on the test side in #10620).

Suggested direction

Pass EnableException = $EnableException in the Select-DbaBackupInformation splat, and check the other internal *-DbaBackupInformation calls in the same pipeline (Get-, Format-, Test-) for the same gap. Whether an empty selection after a warning should also stop the non-exception path is a behavior question worth deciding at the same time.

Created by Claude and reviewed by Andreas Jordan.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions