What's the return value of remove()? The item should have a corresponding general_ref, and not removing both could cause issues. I think there's also a specific_ref or general_ref for tasked items, which remove() should refuse to touch.
Good call, I checked the return value (the fact that it returns a value wasn't documented in the Lua API, so I didn't bother to check before) and it was returning false. A bit of experimentation and looking through the source on github revealed that it wasn't able to remove the item because it was held by a Viewscreen, because I was keeping the barrel inventory open. If the function is called after closing the barrel's inventory, the item is removed successfully.
It's the items::detachItem() function which checks to see if an item is visible in a viewscreen, by the way, which is also called for lots of similar functions, like putOnGround() and moveToContainer(). Quite inconvenient.
So now my problem is figuring out a way to either remove things while viewscreens are open (which I guess would require manually detaching the item from the viewscreen, which could only be done in a plugin, and might cause other problems I can't predict) or delaying removal until the inventory is closed (which would require continuous polling, and might still require doing it in a plugin to be able to detect whether an inventory window is open). Or changing my script to only work on containers, instead of the specific items within them, so the user doesn't need to manually select the item.
Alternatively, I might just be able to fool items::remove() by manually removing the in_inventory flag and adding the removed flag after removing the item from the container.
Incidentally, item::remove() also fails if the item is tasked in any way (by having any specific_ref), so that answers that question.