affaan-m/ECC · error · ContractError
effect recipe must have an integer seed
Error message
effect recipe must have an integer seed
What it means
Every effect recipe must carry an integer seed so its aperiodic schedule is reproducible. The check isinstance(seed, int) and not isinstance(seed, bool) rejects missing, non-int, and bool seeds (bool is a subclass of int in Python, so it is explicitly excluded).
Solutions
- Set recipe['seed'] to a plain Python int, e.g. recipe['seed'] = 42.
- Convert numeric input with int(seed) after verifying it is integral.
- Reject or coerce bools explicitly before validation (bool(seed) is not acceptable).
Example fix
# before
recipe["seed"] = "42"
# after
recipe["seed"] = int("42") Defensive patterns
Strategy: validation
Validate before calling
seed = recipe.get("seed")
if not isinstance(seed, int) or isinstance(seed, bool):
raise ValueError("recipe seed must be a non-bool int") Type guard
def has_int_seed(recipe: dict) -> bool:
seed = recipe.get("seed")
return isinstance(seed, int) and not isinstance(seed, bool) Try / catch
try:
validate_effect_recipe(recipe)
except ContractError as exc:
if "integer seed" in str(exc):
recipe = {**recipe, "seed": int(recipe.get("seed") or 0)}
validate_effect_recipe(recipe)
else:
raise Prevention
- Serialize seeds as JSON numbers, never strings or booleans.
- Reject True/False as seeds in your own config loaders (bool is an int subclass).
- Generate seeds with random.randrange(2**32) to guarantee an int.
When it happens
Trigger: validate_effect_recipe called with a recipe whose 'seed' key is absent, is a float/str/None, or is True/False.
Common situations: Loading recipes from JSON where the seed was serialized as a string; passing a numpy integer or float like 42.0; accidentally setting seed=True; a generator that leaves seed unset when the user declines randomization.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- effect recipe must declare a finite positive timeline…
- Seed must be a nonnegative integer
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/11c53530f77ea889.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:183
if not isinstance(signature, dict) or not _SIGNATURE_AXES.issubset(signature):
raise ContractError(f"genre {spec.get('number')} has an incomplete signature")
if not all(isinstance(signature[axis], list) for axis in _SIGNATURE_AXES):
raise ContractError(f"genre {spec.get('number')} signature axes must be lists")
if not all(signature[axis] for axis in _SIGNATURE_AXES):
raise ContractError(f"genre {spec.get('number')} has an empty signature axis, including avoid")
def validate_effect_recipe(
recipe: dict[str, Any], *, reference_durations: dict[str, float] | None = None
) -> None:
"""Require a seeded aperiodic schedule and anchors on subject-aware effects."""
if (recipe.get("dry_run") is not True
or type(recipe.get("provider_calls")) is not int
or recipe.get("provider_calls") != 0
or recipe.get("provider_execution") is not False):
raise ContractError("effect recipe crosses the dry-run provider boundary")
if not isinstance(recipe.get("seed"), int) or isinstance(recipe.get("seed"), bool):
raise ContractError("effect recipe must have an integer seed")
if recipe.get("rng_algorithm") != "python.random.Random/v1":
raise ContractError("effect recipe must declare its seeded RNG algorithm")
events = recipe.get("events")
if not isinstance(events, list) or len(events) < 3:
raise ContractError("effect recipe needs at least three scheduled events")
timeline = recipe.get("timeline_duration")
if not _is_finite_real(timeline):
raise ContractError("effect recipe must declare a finite positive timeline duration")
timeline = cast(float, timeline)
if float(timeline) <= 0:
raise ContractError("effect recipe must declare a finite positive timeline duration")
for event in events:
start = event.get("time")
duration = event.get("duration")
if (not _is_finite_real(start) or not _is_finite_real(duration)
or float(start) < 0 or float(duration) <= 0):
raise ContractError("effect event start and duration must be finite positive timeline values")
start = cast(float, start)View on GitHub (pinned to 8321021c54)