Billionmail/BillionMail · error

claude script generation: %w

Error message

claude script generation: %w

What it means

GenerateScript calls the Claude (Anthropic-compatible) chat completion API to produce a sales script. If the API client returns an error (HTTP failure, auth failure, rate limit, connection error), it is wrapped with 'claude script generation: %w'.

Source

Thrown at core/internal/service/video_gen/script.go:160

		seconds = 1
	}
	return seconds
}

// GenerateScript calls Claude API to generate a personalized video script.
func GenerateScript(ctx context.Context, cfg ScriptConfig, input ScriptInput) (*ScriptOutput, error) {
	config := openai.DefaultConfig(cfg.APIKey)
	config.BaseURL = cfg.scriptBaseURL()
	client := openai.NewClientWithConfig(config)

	resp, err := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{
		Model:               cfg.Model,
		Messages:            BuildScriptMessages(input),
		MaxCompletionTokens: maxScriptTokens,
		Temperature:         0.7,
	})
	if err != nil {
		return nil, fmt.Errorf("claude script generation: %w", err)
	}

	if len(resp.Choices) == 0 {
		return nil, fmt.Errorf("claude returned no choices")
	}

	script := strings.TrimSpace(resp.Choices[0].Message.Content)
	return &ScriptOutput{
		Script:   script,
		Duration: EstimateDuration(script),
	}, nil
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Read the wrapped cause for the HTTP status / API error body
  2. Verify the LLM API key is present, valid, and has quota (check provider dashboard)
  3. Implement retry with exponential backoff for 429/5xx responses
  4. Confirm the model name in cfg.Model is one the account can access

Example fix

// before
resp, err := client.Chat(ctx, req)
if err != nil {
	return nil, fmt.Errorf("claude script generation: %w", err)
}
// after
resp, err := client.Chat(ctx, req)
if err != nil {
	var apiErr *openai.APIError
	if errors.As(err, &apiErr) && apiErr.HTTPStatusCode == 429 {
		time.Sleep(backoff)
		return generateScriptWithRetry(ctx, cfg, input)
	}
	return nil, fmt.Errorf("claude script generation: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

if cfg.APIKey == "" {
	return fmt.Errorf("LLM API key not configured")
}
if cfg.Model == "" {
	return fmt.Errorf("LLM model not configured")
}

Type guard

func isRetryableLLMError(err error) bool {
	var apiErr interface{ HTTPStatusCode() int }
	if errors.As(err, &apiErr) {
		code := apiErr.HTTPStatusCode()
		return code == 429 || code >= 500
	}
	return errors.Is(err, context.DeadlineExceeded)
}

Try / catch

script, err := GenerateScript(ctx, cfg, input)
var apiErr *APIError
if errors.As(err, &apiErr) && apiErr.HTTPStatusCode == 429 {
	time.Sleep(exponentialBackoff(attempt))
	return GenerateScript(ctx, cfg, input)
}

Prevention

When it happens

Trigger: The chat completion request fails: invalid/missing API key, HTTP 429 rate limit, 5xx from the provider, network failure, or ctx cancellation before the response arrives.

Common situations: ANTHROPIC/LLM API key not set or expired in the deployment; monthly quota or rate limit exhausted during bulk campaign runs; model name typo; network egress blocked from the container.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/cbac24dfccabf7ac. Report an issue: GitHub.