affaan-m/ECC · error · ContractError
effect recipe must declare its seeded RNG algorithm
Error message
effect recipe must declare its seeded RNG algorithm
What it means
To keep schedules reproducible across runs and Python versions, the recipe must explicitly declare its RNG by setting rng_algorithm to the exact sentinel 'python.random.Random/v1'. Any other value (or a missing key) is rejected because the validator cannot guarantee the seed will be interpreted the same way.
Solutions
- Set recipe['rng_algorithm'] = 'python.random.Random/v1' exactly.
- Regenerate the recipe with a current tasteforge generator that emits the algorithm tag.
- Fix typos / version suffixes to match the accepted sentinel string.
Example fix
# before recipe["rng_algorithm"] = "random.Random" # after recipe["rng_algorithm"] = "python.random.Random/v1"
Defensive patterns
Strategy: validation
Validate before calling
if recipe.get("rng_algorithm") != "python.random.Random/v1":
raise ValueError("recipe must declare rng_algorithm 'python.random.Random/v1'") Type guard
def declares_supported_rng(recipe: dict) -> bool:
return recipe.get("rng_algorithm") == "python.random.Random/v1" Try / catch
try:
validate_effect_recipe(recipe)
except ContractError as exc:
if "seeded RNG algorithm" in str(exc):
recipe = {**recipe, "rng_algorithm": "python.random.Random/v1"}
validate_effect_recipe(recipe)
else:
raise Prevention
- Use a shared constant (RNG_ALGO = 'python.random.Random/v1') instead of literals.
- Regenerate old recipes rather than hand-patching the algorithm tag.
- Pin the generator version so emitted recipes always carry the tag.
When it happens
Trigger: validate_effect_recipe called with a recipe missing 'rng_algorithm', or with values like 'random', 'secrets', 'numpy', or a different version tag such as 'python.random.Random/v2'.
Common situations: Recipes generated by older tool versions before the algorithm tag was introduced; switching RNG libraries; hand-edited recipes that omitted the field; typos in the algorithm string.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- -32602
- a claim token is required
- a confirmed nonempty coordinate is required
- a generated candidate cannot claim original-source identity
- A managed install plan with operations is required.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/6c8696520d8f95c3.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:185
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)
duration = cast(float, duration)
if float(start) + float(duration) > float(timeline) + 1e-9:View on GitHub (pinned to 8321021c54)