affaan-m/ECC · error · ClaimError

only a dispatched attempt can become unknown

Error message

only a dispatched attempt can become unknown

What it means

mark_unknown() raises this ClaimError when the claim is not in the 'dispatching' state (and not already 'unknown', which returns silently). Only an attempt that was handed out by begin_dispatch and whose outcome is uncertain may be recorded as unknown; claims that were never dispatched, or that already finished, cannot become unknown.

Solutions

  1. Only call mark_unknown after a begin_dispatch that may or may not have taken effect (e.g. after a crash or transport timeout during dispatching).
  2. Check state first: SELECT state FROM obligation_delivery_claims WHERE token=? and only mark unknown when state == 'dispatching'.
  3. If state is 'unknown' already, no action is needed — the call is intentionally idempotent for that state.
  4. If state is 'claimed', either begin_dispatch normally or cancel(); unknown is not the right transition.

Example fix

// before: called blindly during recovery
claims.mark_unknown(db, token, now=ts)  # ClaimError when never dispatched

// after
row = db.execute("SELECT state FROM obligation_delivery_claims WHERE token=?", (token,)).fetchone()
if row['state'] == 'dispatching':
    claims.mark_unknown(db, token, now=ts)
elif row['state'] == 'claimed':
    claims.cancel(db, token, now=ts)
Defensive patterns

Strategy: validation

Validate before calling

row = db.execute("SELECT state FROM obligation_delivery_claims WHERE token=?", (token,)).fetchone()
if row['state'] != 'dispatching':
    return  # only a dispatched (and uncertain) attempt can become unknown

Try / catch

try:
    claims.mark_unknown(db, token, now=ts)
except claims.ClaimError as e:
    log.warning("mark_unknown refused for %s: %s", token, e)

Prevention

When it happens

Trigger: Calling mark_unknown(db, token) when state is 'claimed' (never dispatched), 'delivered' (already completed), or 'cancelled' — any state other than 'dispatching' or 'unknown'.

Common situations: Calling mark_unknown on a fresh token before begin_dispatch; a retry loop that calls mark_unknown after complete() already ran; misordering recovery logic in a restarted worker.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/52c85fb465a62366. Report an issue: GitHub.

Appendix: source

Thrown at skills/operator-approval-loop/references/approval_claims.py:124

def cancel(db, token, *, now):
    """Cancel only a not-yet-dispatched claim. Never reopen its decision key."""
    with _transaction(db, now):
        row = _claim_row(db, token)
        if row['state'] != 'claimed':
            raise ClaimError('only a pre-dispatch claim can be cancelled')
        db.execute("UPDATE obligation_delivery_claims SET state='cancelled',updated_ts=? WHERE token=?",
                   (now, token))


def mark_unknown(db, token, *, now):
    """Record uncertainty, including a restarted worker's dispatching claim."""
    with _transaction(db, now):
        row = _claim_row(db, token)
        if row['state'] == 'unknown':
            return
        if row['state'] != 'dispatching':
            raise ClaimError('only a dispatched attempt can become unknown')
        db.execute("UPDATE obligation_delivery_claims SET state='unknown',updated_ts=? WHERE token=?",
                   (now, token))


def _finish(db, token, coordinate, now, evidence):
    if not isinstance(coordinate, str) or not coordinate.strip():
        raise ClaimError('a confirmed nonempty coordinate is required')
    with _transaction(db, now):
        row = _claim_row(db, token)
        receipt = db.execute('''SELECT * FROM obligation_deliveries
            WHERE obligation_id=? AND decision_id=?''',
                             (row['obligation_id'], row['decision_id'])).fetchone()
        if row['state'] == 'delivered':
            if receipt is None or receipt['coordinate'] != coordinate or receipt['kind'] != 'draft_sent':
                raise ClaimError('completion contradicts the existing receipt')
            return False
        expected_state = 'dispatching' if evidence is None else 'unknown'
        if row['state'] != expected_state:

View on GitHub (pinned to 8321021c54)