FAILURE MAP
← Case archive

FA-42710 / Listener lifecycle / Member archive

A falsey subscription handle is mistaken for no handle · case 05

A falsey subscription handle is mistaken for no handle; the returned lifecycle plan violates the stated transition contract.

Member previewVariant 5 · 3 implementations · 8 checks per implementation

Case contract

Plan synchronous subscription handshaking. The subscription handle must be installed before source callbacks may request cancellation. If cancellation happens before the source returns teardown, retain a pending-dispose marker and dispose the returned teardown immediately. A thrown subscribe call is distinct from callback failure. A returned empty handle is valid and must not be treated as absence; handle presence has a separate bit. A source throw uses the error channel unless synchronous completion preceded it; after completion it is reported unhandled. First throw is the modeled failure. Error routing follows exception origin, independent of whether a callback ran synchronously inside source initialization. Count cancellation requests received before the first teardown return; if no return has arrived, all cancellations remain deferred. Pending handshakes are first-occurrence unique startup tokens excluding tokens that have finished; a reentrant reuse cannot create a second handle. The source may return a finite list of disposer groups; normalize exactly one grouping level in group order and preserve order within each group. Inputs are finite state snapshots, including transitional and stale states; output fields are the exact independent actions/metadata defined by the corrected expression table. Numeric fixture capacities and counts vary with N. Field definitions, each independently computed from the input snapshot: install = not s['installed'] and s['starting']; pending_dispose = sum(op=='cancel' for op in s['handshake_events'][:s['handshake_events'].index('return')]) if 'return' in s['handshake_events'] else s['handshake_events'].count('cancel'); dispose_returned = s['cancel'] and s['subscribe_returned'] and s['has_teardown'] and not s['disposed']; presence = s['has_handle']; source_error = ('unhandled' if 'complete' in s['start_trace'][:s['start_trace'].index('throw')] else 'error-channel') if 'throw' in s['start_trace'] else None; callback_error = {'source':'subscription-error','callback':'callback-error'}[s['raised_by']] if s['raised_by'] is not None else None; ready = s['installed'] and s['subscribe_returned'] and s['source_error'] is None and not s['cancel']; retain_teardown = [item for group in s['teardown_groups'] for item in group]; reentrant_start = [x for x in dict.fromkeys(s['start_tokens']) if x not in s['finished_tokens']]; handle_value = s['handle'] if s['has_handle'] else None

Why this case matters

Observer implementations need to preserve this state while subscriptions enter, execute, and leave their lifecycle.

One recorded failure

Sample boundary fixture

This sample comes from the broken implementation of a controlled reproducer.

Boundary fixtureActualExpectedOutcome
transition 0{"callback_error": null, "dispose_returned": false, "handle_value": null, "install": false, "pending_dispose": 2, "presence": true, "ready": false, "reentrant_start": ["a", "b"], "retain_teardown": ["a", "b", "c"], "source_error": "unhandled"}{"callback_error": null, "dispose_returned": false, "handle_value": null, "install": false, "pending_dispose": 2, "presence": false, "ready": false, "reentrant_start": ["a", "b"], "retain_teardown": ["a", "b", "c"], "source_error": "unhandled"}Failed

MEMBER ARCHIVE

The complete case is available to members.

This record includes three runnable implementations, regression fixtures, execution results, and source hashes.

Member access is invitation-based. Sign in with your invited account to inspect the sources.

Sign in to the archive ↗