← 1.0.0 backlogs ISS-21

The most declaration-shaped refusal of all reads as "failed"

Type
Bug — a public surface that will be expensive to correct later
Found while
SAPE-14
Triage
Fix in 1.0.0
Status
Open
Severity
Medium in effect, high in timing — adding the code now is additive; adding it after 1.0.0 breaks whoever branched on "failed"

Description

codeFor (internal/server/server.go:1104) maps 21 errors to the code a client receives. store.ErrIncompatible is not one of them — grep -c ErrIncompatible internal/server/server.go returns 0. So the refusal

this does not match what was declared before: the primary key of "notes" was declared …

reaches the caller as code "failed", indistinguishable from a disk error, a closed database, or any other mishap. It is, of all the refusals this server makes, the one most purely about a declaration — and it is the one that arrives with no name.

Why it only matters now

SAPE-14 is what put this within reach. Before it, ErrIncompatible could only be raised offline, inside sapedb apply, where a human reads the sentence and understands it. SAPE-14 sent it down the establish frame, where a program has to switch on a code. The error did not change; the audience did.

Evidence

Triage

Does it lose data, break a promise on a public surface, or stop somebody installing and running? Yes — the second, by way of timing.

Not because the bug is heavy. Because codeFor is a public surface, and 1.0.0 freezes it. Ship with this reading as "failed" and clients will write handling branches keyed on "failed" — at which point giving the error its real code breaks them. Adding it today is an addition. Adding it after the tag is a change.

What the fix is