{"record":{"id":"697be0a8eae0e467","repo":"ScrapeGraphAI/Scrapegraph-ai","slug":"input-tokens-is-required-for-completion-costs-with","errorCode":null,"errorMessage":"input_tokens is required for completion costs with tiered pricing","messagePattern":"input_tokens is required for completion costs with tiered pricing","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapegraphai/utils/custom_callback.py","lineNumber":53,"sourceCode":"    Args:\n        model_name: Name of the model\n        num_tokens: Number of tokens.\n        is_completion: Whether the model is used for completion or not.\n            Defaults to False.\n        input_tokens: Number of input tokens used to select a pricing tier.\n        service_tier: Provider service tier. Defaults to standard.\n\n    Returns:\n        Cost in USD.\n    \"\"\"\n    if (\n        model_name not in MODEL_COST_PER_1K_TOKENS_INPUT\n        and model_name not in MODEL_COST_TIERS_PER_1K_TOKENS\n    ):\n        return 0.0\n    if input_tokens is None:\n        if is_completion and model_name in MODEL_COST_TIERS_PER_1K_TOKENS:\n            raise ValueError(\n                \"input_tokens is required for completion costs with tiered pricing\"\n            )\n        input_tokens = num_tokens\n    rate = get_model_cost_per_1k_tokens(\n        model_name,\n        input_tokens,\n        is_completion=is_completion,\n        service_tier=service_tier,\n    )\n    return rate * (num_tokens / 1000)\n\n\nclass CustomCallbackHandler(BaseCallbackHandler):\n    \"\"\"Callback Handler that tracks LLMs info.\"\"\"\n\n    total_tokens: int = 0\n    prompt_tokens: int = 0\n    completion_tokens: int = 0","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/ScrapeGraphAI/Scrapegraph-ai/blob/532dfffbf6ee823a6c9cf8cfedc24a93bf026780/scrapegraphai/utils/custom_callback.py#L35-L71","documentation":"ValueError from get_token_cost_for_model: for models with tiered (token-volume-dependent) pricing, the completion/output rate depends on the input token count, so input_tokens must be supplied to compute completion costs. Without it the correct tier cannot be selected.","triggerScenarios":"Calling on_llm_end / get_token_cost_for_model with is_completion=True for a model listed in MODEL_COST_TIERS_PER_1K_TOKENS (e.g. MiniMax M3) without passing input_tokens.","commonSituations":"Custom LangChain callbacks tracking costs for tiered-pricing models where only the response (num_tokens) is available from the LMLOutput.","solutions":["Pass input_tokens (the prompt token usage from response.llm_output) alongside num_tokens when computing completion cost","Upgrade/patch the callback so on_llm_end extracts token_usage.prompt_tokens and forwards it","If tiering is irrelevant, use a model without tiered pricing"],"exampleFix":"# before\ncost = get_token_cost_for_model(model, num_tokens=output_tokens, is_completion=True)\n# after\ncost = get_token_cost_for_model(model, num_tokens=output_tokens, input_tokens=prompt_tokens, is_completion=True)","handlingStrategy":"validation","validationCode":"usage = response.llm_output.get(\"token_usage\", {}) if response.llm_output else {}\ninput_tokens = usage.get(\"prompt_tokens\")\nif model in MODEL_COST_TIERS_PER_1K_TOKENS and is_completion and input_tokens is None:\n    input_tokens = usage.get(\"total_tokens\", 0)","typeGuard":"def has_input_tokens(response) -> bool:\n    llm_out = getattr(response, \"llm_output\", None) or {}\n    return bool((llm_out.get(\"token_usage\") or {}).get(\"prompt_tokens\") is not None)","tryCatchPattern":"try:\n    cost = get_token_cost_for_model(model, n, input_tokens=inp, is_completion=True)\nexcept ValueError:\n    cost = 0.0  # skip untracked completion","preventionTips":["Always extract prompt_tokens from llm_output in on_llm_end","Default missing prompt token counts to 0, never omit","Unit-test cost callbacks against tiered-pricing models"],"tags":["token-usage","cost-tracking","tiered-pricing"],"backgroundTag":"missing-required-parameter","analyzedSha":"532dfffbf6ee823a6c9cf8cfedc24a93bf026780","analyzedAt":"2026-08-28T15:19:38.821Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}