Sanity Library Reference Docs
    Preparing search index...
    DisabledReason:
        | { detail?: string; filter: string; kind: "filter-failed" }
        | { kind: "cascade-fired"; when: string }
        | { kind: "activity-not-active"; status: TerminalActivityStatus }
        | { kind: "stage-terminal"; stage: StageName }
        | { denied: DeniedGuardRef[]; kind: "mutation-guard-denied" }
        | { completedAt: string; kind: "instance-completed" }
        | { abortedAt: string; kind: "instance-aborted" }
        | {
            kind: "requirements-unmet";
            unmetRequirements: RequirementDescriptor[];
        }
        | { denied: SubjectPermissionDenial[]; kind: "subject-permission-denied" }

    Why an action is disabled for this actor right now — the read-side verdict.

    Verdict↔exception mapping (what fireAction throws when the verdict says no): the mutation-guard-denied arm escalates to MutationGuardDeniedError — the one guard-denial error, shared by every verb; every other arm is thrown as ActionDisabledError carrying the verdict as reason. The edit seam mirrors this: see EditDisabledReason and EditFieldDeniedError.

    Type declaration

    • { detail?: string; filter: string; kind: "filter-failed" }
      • Optionaldetail?: string
      • filter: string
      • kind: "filter-failed"

        The action's condition evaluated falsy for this actor — the ONE engine-side gate (advisory, like every engine check). Sugar like roles desugared into this condition, so a role miss surfaces here too. Under filter-existence semantics a consumer renders the action ABSENT, never disabled.

    • { kind: "cascade-fired"; when: string }
      • kind: "cascade-fired"

        The action is cascade-fired (when) — the engine's cascade is its only firing path; fireAction rejects it for every caller.

      • when: string
    • { kind: "activity-not-active"; status: TerminalActivityStatus }
    • { kind: "stage-terminal"; stage: StageName }
    • { denied: DeniedGuardRef[]; kind: "mutation-guard-denied" }
      • denied: DeniedGuardRef[]
      • kind: "mutation-guard-denied"

        A deployed mutation guard denies the instance write every action commit performs. Advisory pre-flight — the engine's optimistic evaluation; denied is the same DeniedGuardRef shape the thrown MutationGuardDeniedError carries.

    • { completedAt: string; kind: "instance-completed" }
    • { abortedAt: string; kind: "instance-aborted" }
      • abortedAt: string
      • kind: "instance-aborted"

        The instance was hard-stopped via abortInstance. Aborted instances carry completedAt too, so this arm wins over instance-completed (the terminalState precedence).

    • { kind: "requirements-unmet"; unmetRequirements: RequirementDescriptor[] }
      • kind: "requirements-unmet"

        The activity's declared Activity.requirements aren't all satisfied — the readiness axis. The activity is visible and the actor authorized, but its own preconditions don't hold yet. unmetRequirements carries the authored descriptors so a consumer can disable the affirmative control and say which precondition is outstanding. Distinct from filter-failed (visibility/authorization) and mutation-guard-denied (content-write).

      • unmetRequirements: RequirementDescriptor[]
    • { denied: SubjectPermissionDenial[]; kind: "subject-permission-denied" }
      • denied: SubjectPermissionDenial[]
      • kind: "subject-permission-denied"

        The actor's grants on an involved subject's resource don't allow the content write the action's effects would perform there. Forecast per-resource: each subject named by a doc.ref/subject/doc.refs/release.ref field entry outside the workflow's own resource is checked against THAT resource's ACL. Advisory like every engine verdict — the subject's lake still enforces; and it degrades open: a resource whose grants can't be fetched is simply not forecast.