calesthio/OpenMontage · error · ValueError

music_gen.estimate_cost: duration_seconds is required. Deriv

Error message

music_gen.estimate_cost: duration_seconds is required. Derive it from the approved target runtime in the script/proposal. Silent defaults are not permitted.

What it means

Raised by music_gen.estimate_cost when inputs lacks duration_seconds. ElevenLabs music pricing is approximated per 30 seconds of runtime ($0.05/30s), so a duration is mandatory; the project explicitly forbids silent defaults because cost approval must be grounded in the approved target runtime from the script/proposal.

Source

Thrown at tools/audio/music_gen.py:105

        cpu_cores=1, ram_mb=256, vram_mb=0, disk_mb=50, network_required=True
    )
    retry_policy = RetryPolicy(max_retries=2, retryable_errors=["rate_limit", "timeout"])
    idempotency_key_fields = ["prompt", "duration_seconds"]
    side_effects = ["writes audio file to output_path", "calls ElevenLabs API"]
    user_visible_verification = [
        "Listen to generated music for mood and quality",
    ]

    def get_status(self) -> ToolStatus:
        if os.environ.get("ELEVENLABS_API_KEY"):
            return ToolStatus.AVAILABLE
        return ToolStatus.UNAVAILABLE

    def estimate_cost(self, inputs: dict[str, Any]) -> float:
        # ElevenLabs music generation pricing is per generation
        duration = inputs.get("duration_seconds")
        if duration is None:
            raise ValueError(
                "music_gen.estimate_cost: duration_seconds is required. "
                "Derive it from the approved target runtime in the script/proposal. "
                "Silent defaults are not permitted."
            )
        # Approximate: ~$0.05 per 30 seconds
        return round(duration / 30 * 0.05, 4)

    def execute(self, inputs: dict[str, Any]) -> ToolResult:
        api_key = os.environ.get("ELEVENLABS_API_KEY")
        if not api_key:
            return ToolResult(
                success=False,
                error="No ElevenLabs API key. " + self.install_instructions,
            )

        start = time.time()

        try:

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Derive duration_seconds from the approved target runtime in the script/proposal and pass it in inputs
  2. Order pipeline stages so cost estimation runs after runtime approval
  3. Add an upstream schema check that fails fast listing duration_seconds as required

Example fix

// before
inputs = {"prompt": "cinematic intro"}
tool.estimate_cost(inputs)  # raises

// after
inputs = {"prompt": "cinematic intro", "duration_seconds": 60}
tool.estimate_cost(inputs)  # 0.1
Defensive patterns

Strategy: validation

Validate before calling

duration = inputs.get("duration_seconds")
if duration is None:
    raise ValueError(
        "duration_seconds required: derive from the approved target runtime in the script/proposal"
    )

Prevention

When it happens

Trigger: Planner/orchestrator calls estimate_cost before duration is known; inputs assembled from a template without the runtime field; execute-time cost accounting hitting the same check.

Common situations: Automated cost-preview passes that probe tools with incomplete inputs; new pipeline stages added before the script's runtime is approved; key named differently (duration, length_seconds).

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/ddc0c4090d647a48. Report an issue: GitHub.