affaan-m/ECC · error · ValueError
source_availability_policy must be allow_unavailable or…
Error message
source_availability_policy must be allow_unavailable or require_available
What it means
run_workflow validates the workflow config dict before doing any work. The source_availability_policy key must be exactly one of the two allowed strings, 'allow_unavailable' or 'require_available'; anything else (typo, wrong case, wrong type like None or true) raises this ValueError. It exists because the policy controls whether missing source files are tolerated downstream.
Solutions
- Set source_availability_policy to exactly 'allow_unavailable' (default) or 'require_available', lowercase string
- If the key was meant to be omitted, remove it — the default is 'allow_unavailable'
- Validate the value in your config loader before calling run_workflow
Example fix
// before
config = {'schema_version': 1, 'dry_run': True, 'source_availability_policy': 'require'}
// after
config = {'schema_version': 1, 'dry_run': True, 'source_availability_policy': 'require_available'} Defensive patterns
Strategy: validation
Validate before calling
ALLOWED_POLICIES = {'allow_unavailable', 'require_available'}
if config.get('source_availability_policy', 'allow_unavailable') not in ALLOWED_POLICIES:
raise ValueError('source_availability_policy must be allow_unavailable or require_available') Type guard
def is_valid_policy(v) -> bool:
return isinstance(v, str) and v in {'allow_unavailable', 'require_available'} Try / catch
try:
run_workflow(config, out_dir)
except ValueError as e:
if 'source_availability_policy' in str(e):
config['source_availability_policy'] = 'allow_unavailable'
run_workflow(config, out_dir)
else:
raise Prevention
- Use a literal or enum constant for the policy value instead of a raw string
- Load workflow configs through a schema validator (pydantic/jsonschema) with an enum field
- Copy policy values from existing working configs
When it happens
Trigger: Passing config['source_availability_policy'] set to any value other than 'allow_unavailable' or 'require_available' — e.g. 'Require_Available', 'required', None, a boolean, or omitting quotes in a JSON config.
Common situations: Hand-edited config files with a typo or wrong casing; programmatic config built with a raw string that was never validated; YAML/JSON config where the field was set to a boolean like true instead of a 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
- Choose at least one guided harness: Claude, Codex, or Kimi.
- failure.reason
- genre has no references
- Invalid : unsupported hook event
- invalid plan-canvas server port
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/430cce6034ae76bf.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/workflow.py:542
"""Execute the deterministic offline contract and return its receipt."""
config_path = Path(config_path)
out_dir = Path(out_dir)
config = json.loads(config_path.read_text(encoding="utf-8"))
probe = probe or probe_media
def resolve_input(raw_path: str) -> Path:
candidate = Path(raw_path).expanduser()
if not candidate.is_absolute():
candidate = config_path.parent / candidate
return Path(os.path.abspath(candidate))
if config.get("schema_version") != 1:
raise ValueError("workflow schema_version must be 1")
if config.get("dry_run", True) is not True:
raise ValueError("workflow requires dry_run=true; provider execution is disabled")
source_policy = config.get("source_availability_policy", "allow_unavailable")
if source_policy not in {"allow_unavailable", "require_available"}:
raise ValueError("source_availability_policy must be allow_unavailable or require_available")
genres = sorted(config.get("genres", []), key=lambda item: item["number"])
if not genres:
raise ValueError("workflow needs at least one numbered genre")
output = _SafeOutput(out_dir)
output.prepare(("genres", "manifests", "resolve"))
references: list[dict[str, Any]] = []
specs: list[dict[str, Any]] = []
manifests: dict[str, dict[str, Any]] = {
modality: {
"schema_version": 1,
"modality": modality,
"dry_run": True,
"submit": False,
"provider_calls": 0,
"provider_execution": False,
"requests": [],View on GitHub (pinned to 8321021c54)