Skip to content

Approved confirmations silently discard attachments #38

@unspecifiedcoder

Description

@unspecifiedcoder

Summary

processConfirmationResponse in src/server/processor/confirmation/confirmation.service.ts:172-199 only appends the attachment block to denialReason when !approved:

let denialReason: string | undefined;
if (!approved) {
    const attachmentBlock = formatConfirmationAttachmentBlock(response.attachments);
    ...
}

A confirmation response with selectedOptionId: 'yes' (or 'yes_dont_ask') plus a non-empty attachments array therefore has the attachments silently discarded. The client guard at src/client/app.tsx:1375-1377 only forwards attachments for optionId === 'guidance' || operation === 'ask_user', so the GUI doesn't exercise this path, but the server contract is implicit and asymmetric:

  • The REST schema (routes/automations.ts) accepts any selectedOptionId + attachments
  • The WS handler (routes/ws/commands/confirmation-response.ts) accepts any selectedOptionId + attachments
  • Only formatConfirmationAttachmentBlock decides what reaches the model — and only on the !approved branch

Impact

Low frequency under the current GUI, but real for:

  • Programmatic API consumers (REST + WS)
  • Future client code that forgets the contract
  • A potential future "ask_user-style" approval flow that wants to attach context

The data-loss is silent: no 400, no log, no client-visible signal.

Proposed fix

Reject the YES + attachments combination at the transport boundary so the contract is explicit. The client guard already enforces this for the GUI; the server should match.

I have a fix ready and will open a PR shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions