adobe / adobe/aio-cli-plugin-runtime
rt package delete --recursive fails for packages with feed-backed triggers (wrong field name in recursivelyDeletePackage)
- Dominant language
- JavaScript
- Stars
- 21
- Forks
- 33
- PR merge metrics
- No merged PRs in 30d
Description
## Bug report
`aio rt package delete --recursive` fails to delete a package when one of its actions is bound (via a rule) to a **feed-backed trigger** (e.g. `/whisk.system/alarms/interval`, `/whisk.system/alarms/alarm`).
### Observed error
```
Error: failed to delete the package: Missing mandatory trigger parameter from options.
```
### Root cause
In [`src/commands/runtime/package/delete.js`](https://github.com/adobe/aio-cli-plugin-runtime/blob/master/src/commands/runtime/package/delete.js), `recursivelyDeletePackage()` builds the trigger reference for each rule with the wrong field name:
```js
const ruleData = {
ruleName: rule.name,
trigger: {
namespace: rule.trigger.path,
triggerName: rule.trigger.name // <-- should be `name`, not `triggerName`
}
}
...
deleteEntitiesPromises.push(ow.triggers.delete(actionRule.trigger), ow.rules.delete(actionRule.ruleName))
```
This object is passed straight into `ow.triggers.delete(...)`, which resolves to `@adobe/aio-lib-runtime`'s wrapped `Triggers.delete()` (src/triggers.js):
```js
async delete (options) {
const retTrigger = await this.owclient.triggers.get(options) // succeeds: raw openwhisk client accepts `triggerName` as a fallback identifier
if (retTrigger.annotations) {
for (const annotation of retTrigger.annotations) {
if (annotation.key === 'feed') {
await this.owclient.feeds.delete({ name: annotation.value, trigger: options.name }) // <-- reads options.name specifically
}
}
}
return this.owclient.triggers.delete(options)
}
```
Since the passed-in object only has `triggerName` (not `name`), `options.name` is `undefined`. This is then passed to `openwhisk-client-js`'s `Feeds.feed()`, which validates the `trigger` param and throws:
```js
if (!this.triggerName(options)) {
throw new Error(messages.MISSING_FEED_TRIGGER_ERROR) // 'Missing mandatory trigger parameter from options.'
}
```
### Impact
Because `Promise.all(deleteEntitiesPromises)` rejects as soon as any one deletion throws, the trailing `ow.packages.delete(pkg)` call in `recursivelyDeletePackage` never executes. This means:
1. The package itself is never deleted when this happens (not just the feed deregistration).
2. The feed (e.g. the alarms provider registration backing an interval/alarm trigger) is never properly deregistered via this path, since the `feeds.delete()` call throws before reaching the underlying HTTP call.
### Repro steps
1. Deploy a manifest with an action, a feed-backed trigger, and a rule connecting them, e.g.:
```yaml
triggers:
every-5-min:
feed: /whisk.system/alarms/interval
inputs:
minutes: 5
rules:
fire-every-5-min:
trigger: every-5-min
action: someAction
```
2. `aio app deploy` (or `aio rt trigger create` + `aio rt rule create` directly).
3. `aio rt package delete --recursive`
4. Observe: `Error: failed to delete the package: Missing mandatory trigger parameter from options.`
### Suggested fix
In `recursivelyDeletePackage`, use `name` instead of `triggerName` when building the trigger reference:
```js
trigger: {
namespace: rule.trigger.path,
name: rule.trigger.name
}
```
### Environment
- `aio-cli-plugin-app`: 14.8.1 (observed via `aio info`)
- `aio-cli`: 11.1.2
- Node: 24.6.0
Contributor guide
Research direction
Start in src/commands/runtime/package/delete.js at recursivelyDeletePackage(), then trace the trigger deletion call and the referenced Triggers.delete() behavior in src/triggers.js. Reproduce with a feed-backed trigger and recursive package deletion; done means the package, rule, trigger, and feed are deleted without the missing-trigger-parameter error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100