Skip to content

feat: support ao.unset sentinel for patch field removal#829

Merged
jfrain99 merged 1 commit intoedgefrom
feat/patch-unset
Apr 10, 2026
Merged

feat: support ao.unset sentinel for patch field removal#829
jfrain99 merged 1 commit intoedgefrom
feat/patch-unset

Conversation

@Lucifer0x17
Copy link
Copy Markdown
Collaborator

@Lucifer0x17 Lucifer0x17 commented Apr 9, 2026

Summary

  • Adds convert_unset_values/1 to dev_json_iface that recursively converts <<"__ao-unset__">> sentinel strings to the unset atom during JSON result deserialization
  • Applied in both preprocess_results (outbox messages) and json_to_message (patches path)
  • dev_message:set/3 already handles the unset atom by removing those keys -- no changes needed there

Problem

When AOS processes use patch@1.0 to cache state for frontend HTTP access, removing a field from a nested map is impossible. Lua nil deletes the key from the table before serialization, so the patch system never learns the field should be removed. The deep merge in dev_message:set preserves old keys that are absent from the new patch.

Solution

A sentinel value "__ao-unset__" that survives Lua table serialization and JSON encoding. At the HB boundary (dev_json_iface), it is converted to the unset atom that dev_message:set already handles.

Requires a companion change in the AOS repo: ao.unset = "__ao-unset__" in ao.lua.

Usage

ao.unset = "__ao-unset__"  -- defined once in ao.lua

-- Remove cherry from nested map, update apple, keep banana
Send({device="patch@1.0", prices={apple="200", cherry=ao.unset}})

-- Clear a top-level key (set to empty map)
Send({device="patch@1.0", mode={}})

When AOS processes use patch@1.0 to cache state, Lua nil removes keys from tables before serialization, making it impossible to express "remove this field" in a patch. This adds convert_unset_values/1 to dev_json_iface which converts the "__ao-unset__" sentinel string to the unset atom during JSON result deserialization. dev_message:set/3 already handles the unset atom by removing those keys.

Usage from Lua: `Send({device="patch@1.0", prices={cherry=ao.unset}})`
Requires ao.unset = "__ao-unset__" defined in ao.lua (AOS repo).
@Lucifer0x17 Lucifer0x17 self-assigned this Apr 9, 2026
@Lucifer0x17 Lucifer0x17 requested a review from jfrain99 April 9, 2026 18:30
@Lucifer0x17 Lucifer0x17 added the bug Something isn't working label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants