affaan-m/ECC · error · ValueError

workflow requires dry_run=true; provider execution is…

Error message

workflow requires dry_run=true; provider execution is disabled

What it means

run_workflow enforces the deterministic offline contract: candidate execution is disabled on every OS because no verified containment backend exists, so the workflow config must set dry_run=true and any provider-execution request is refused.

Solutions

  1. Set "dry_run": true (boolean) in the workflow config
  2. Remove the dry_run key entirely — true is the default
  3. If provider execution is needed, use a build/version of the tool that enables it

Example fix

// before
"dry_run": false
// after
"dry_run": true
Defensive patterns

Strategy: validation

Validate before calling

if config.get("dry_run", True) is not True:
    raise SystemExit("dry_run must be boolean true in this build; provider execution is disabled")

Type guard

def is_dry_run(config: dict) -> bool:
    return config.get("dry_run", True) is True

Try / catch

try:
    run_workflow(config)
except ValueError as e:
    if "dry_run" in str(e):
        config["dry_run"] = True
        run_workflow(config)
    else:
        raise

Prevention

When it happens

Trigger: Config contains "dry_run": false, or a truthy non-true value like "true" (string) or 1, which fails the strict `is not True` check.

Common situations: Users flipping dry_run to false expecting provider calls to work; YAML/JSON writers emitting the string "true"; older configs predating the dry-run-only enforcement.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/workflow.py:539


def run_workflow(config_path: str | Path, out_dir: str | Path, *, probe: Probe | None = None) -> dict[str, Any]:
    """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,

View on GitHub (pinned to 8321021c54)