Verse Wiki — the Verse handbook for Blueprint authors
Deep Dive · EXTRA

Why Can Assigning into a map "Fail" Too? The Effect-System Design Debate

Writing a row into a map either inserts or overwrites — by any reading it should never "not go through." Yet on the official Epic forums, someone actually slammed that exact question onto the table for you. This page lets you sit in on the debate, and along the way see why Verse stamps so many operations with "might not go through."

1. A Perfectly Reasonable Question

Developer ZeroYaHero posted on the official Epic forums: why must if (set MyMap[Key] = Value) be wired into a Branch at all? Intuitively, writing a value to a key in a map has exactly two endings — key absent, insert; key present, overwrite. It works either way, so where does "not going through" come from? But Verse's Compile is incorruptible: writing a value to some key in a map wears the "might not go through" stamp, gets no pass without a Branch, and lights up red with that classic error: "This invocation calls a function that has the 'decides' effect, which is not allowed by its context."

failable_set_demo.verse
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }

failable_set_demo := class(creative_device):

    var Scores:[string]int = map{}

    OnBegin<override>()<suspends>:void =
        # Compile error: 'decides' effect not allowed by its context
        # set Scores["A"] = 1

        # The right move: wrap it in a failure context
        if (set Scores["A"] = 1):
            Print("A registered")

        # Compound assignment really can fail: B was never registered, the read dies first
        if (set Scores["B"] += 1):
            Print("This line never runs")
        else:
            Print("B does not exist, += failed and rolled back")

Graph read-through: three parts inside one Event BeginPlay. Part one is the commented-out cautionary tale — set Scores["A"] = 1 written without a Branch won't pass Compile. Part two is the right way: wired into a Branch; it goes through, so Print String logs "A registered." Part three does an "add 1 onto the current value" on the never-registered "B" — the read finds no such entry, so it takes else and prints the failure notice. Note: on the line that didn't go through, any changes it had already tried to write get fully undone (rolled back), as if they never happened.

2. The Community's Explanation: Guilt by Association with "Add onto the Current Value"

The most convincing reply came from Sprintermax: the key lies in the "add/subtract onto the current value" spellings, += and -=. set M[K] += 1 must first read the old value out, compute, then write it back; when the key doesn't exist, that read genuinely can't go through — not design fussiness, but logical necessity. And Verse treats "writing a value to some key in a map" as one whole family: the plain "direct write" and "add onto the current value" share the same write machinery, so the entire family gets stamped "might not go through," no exceptions.

Other replies guessed the reason hides in the engine's internals — safe handling when several wires access it at once, for instance. The discussion's closing verdict was refreshingly frank: the most ordinary "direct write" logically could always go through, but the language just isn't designed that way. In other words, this isn't a Compile bug — it's consistency the language authors chose on purpose.

3. Those "Might Not Go Through" Stamps Are Playing a Long Game

Pull the camera back and you'll see Verse's core philosophy: "this operation might not go through" isn't expressed by erroring out and crashing the game at runtime — it's stamped plainly on the operation's nameplate: that "might not go through" stamp. Unify the nameplates and you unify your mental model: every square-bracket access by position or by key — array read, array write, map read, map write — might not go through, and every one gets wired into a Branch. You never have to memorize an exceptions list of "which ones go through and which don't."

The cost? Occasionally wiring a Branch around an operation that "obviously always goes through," which looks wordy. The payoff? Every path that might not go through is laid on the table the moment you hit Compile, plus a rollback bonus — it's like test-wiring your nodes on a shadow graph first: if the line doesn't go through, every change made during the test-wiring is voided on the spot, and the real graph never moves a pixel. Language design often forces a choice between local intuition and global consistency; here, Verse picked the latter without blinking.

A practical cheat note: when you don't need the else side, close with the one-liner if (set M[K] = V) {} — that empty {} pair is "else does nothing." Readers will parse it as "a write that always goes through"; formally it obeys the rules, mentally it costs nothing.

Per the forum's mainstream explanation, why does set Scores[K] += 1 (add 1 onto the current value) on a nonexistent key K not go through?

Sources

Compiled from the Epic developer forums and official documentation:

Why is setting a key value in a map type failable in Verse? (Epic Developer Forums) ↗
Map in Verse (Official Docs) ↗