s3: no safeguard for recursive delete; rb fails on non-empty buckets #11

Closed
opened 2026-03-20 20:49:45 +00:00 by barrettruth · 0 comments
barrettruth commented 2026-03-20 20:49:45 +00:00

Problem

Two related issues with destructive S3 operations:

1. Recursive delete has no opt-out.
`aws s3 rm --recursive s3://bucket/prefix/` deletes all matching objects atomically and unrecoverably. Canola passes `--recursive` whenever `entry_type == 'directory'` with no confirmation and no way to disable it. A mis-aimed delete on a large prefix could silently wipe thousands of objects.

2. `rb` (remove bucket) silently fails on non-empty buckets.
`s3fs.rb` runs `aws s3 rb` without `--force`, which the AWS CLI requires to empty and remove a non-empty bucket. The operation fails silently (the CLI returns a non-zero exit code which surfaces as an error, but the bucket is left intact with no clear message).

Proposed solution

Add a config flag — either at the per-adapter level or globally — to gate recursive operations:

-- global default (vim.g.canola)
vim.g.canola = { allow_recursive_delete = false }

-- per-adapter override takes precedence
vim.g.canola_s3 = { allow_recursive_delete = true }

When `allow_recursive_delete = false` (the proposed default), attempting to delete a non-empty S3 "folder" would return an error rather than silently deleting everything. For `rb`, the same flag could gate whether to pass `--force`.

Decision needed: should the flag live at `vim.g.canola` (global) with per-adapter overrides, or only at the per-adapter level? The global approach is safer as a default; per-adapter override allows trusted buckets to opt in.

## Problem Two related issues with destructive S3 operations: **1. Recursive delete has no opt-out.** \`aws s3 rm --recursive s3://bucket/prefix/\` deletes all matching objects atomically and unrecoverably. Canola passes \`--recursive\` whenever \`entry_type == 'directory'\` with no confirmation and no way to disable it. A mis-aimed delete on a large prefix could silently wipe thousands of objects. **2. \`rb\` (remove bucket) silently fails on non-empty buckets.** \`s3fs.rb\` runs \`aws s3 rb\` without \`--force\`, which the AWS CLI requires to empty and remove a non-empty bucket. The operation fails silently (the CLI returns a non-zero exit code which surfaces as an error, but the bucket is left intact with no clear message). ## Proposed solution Add a config flag — either at the per-adapter level or globally — to gate recursive operations: ```lua -- global default (vim.g.canola) vim.g.canola = { allow_recursive_delete = false } -- per-adapter override takes precedence vim.g.canola_s3 = { allow_recursive_delete = true } ``` When \`allow_recursive_delete = false\` (the proposed default), attempting to delete a non-empty S3 "folder" would return an error rather than silently deleting everything. For \`rb\`, the same flag could gate whether to pass \`--force\`. Decision needed: should the flag live at \`vim.g.canola\` (global) with per-adapter overrides, or only at the per-adapter level? The global approach is safer as a default; per-adapter override allows trusted buckets to opt in.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
barrettruth/canola-collection#11
No description provided.