Billionmail/BillionMail · error
error marshalling prompt config: %v
Error message
error marshalling prompt config: %v
What it means
ModifyPrompt serializes the updated PromptConfig with json.Marshal before writing it to prompt_config.json. This error is returned if marshalling fails. For a simple struct of strings/ints this is nearly impossible at runtime (only channels, funcs, or cycles break json.Marshal), so seeing it usually signals a schema change that added an unsupported field type to PromptConfig.
Source
Thrown at core/internal/service/askai/project.go:830
// ModifyPrompt updates the prompt configuration for a given domain.
// It reads the existing prompt configuration, modifies the specified fields, and saves the updated configuration back to the file.
// If the prompt is empty, it will not be updated.
func ModifyPrompt(Domain string, Prompt string) error {
config, err := GetPrompt(Domain)
if err != nil {
return fmt.Errorf("error getting prompt config: %v", err)
}
// Update the prompt configuration
if Prompt != "" {
config.Prompt = Prompt
}
config.UpdateTime = public.GetNowTime()
filename := fmt.Sprintf(PRODUCT_CONFIG_PATH+"/%s/prompt_config.json", Domain)
data, err := json.Marshal(config)
if err != nil {
return fmt.Errorf("error marshalling prompt config: %v", err)
}
err = os.WriteFile(filename, data, 0644)
if err != nil {
return fmt.Errorf("error saving prompt config file: %v", err)
}
return nil
}
type BotResponse struct {
Data BotData `json:"data"`
Msg string `json:"msg"`
Status bool `json:"status"`
}
type BotData struct {
Description string `json:"description"`
Domain string `json:"domain"`
Markdown string `json:"markdown"`View on GitHub (pinned to fc36c76c05)
Solutions
- Check the wrapped error for 'json: unsupported type: ...' to find the offending field type
- Tag non-serializable fields with json:"-" so they are excluded from marshalling
- Implement MarshalJSON on the offending type, or store it as a plain serializable value
- Keep PromptConfig limited to JSON-safe types (string, int, bool, slices, nested structs)
Example fix
// before
type PromptConfig struct {
Prompt string `json:"prompt"`
UpdateHook func() `json:"update_time"` // unsupported type
}
// after
type PromptConfig struct {
Prompt string `json:"prompt"`
UpdateTime int64 `json:"update_time"`
UpdateHook func() `json:"-"` // excluded from JSON
} Defensive patterns
Strategy: validation
Validate before calling
// check PromptConfig is JSON-serializable before saving
func promptConfigIsSerializable(cfg PromptConfig) bool {
b, err := json.Marshal(cfg)
return err == nil && b != nil
}
// usage:
if !promptConfigIsSerializable(config) {
log.Fatal("PromptConfig contains non-JSON-serializable fields")
} Try / catch
if err := ModifyPrompt(domain, prompt); err != nil {
if strings.Contains(err.Error(), "unsupported type") {
log.Printf("PromptConfig has non-serializable field: %v", err)
// fix struct tags before retrying
}
return err
} Prevention
- Keep PromptConfig limited to JSON-safe types; tag helpers with json:"-"
- Add a unit test that marshals a fully-populated PromptConfig
- Run `go vet` and marshal tests whenever the struct changes
- Avoid embedding interfaces, funcs, or channels in persisted config structs
When it happens
Trigger: A struct type inside PromptConfig (or a field added to it) that json.Marshal cannot encode — e.g. a func, channel, or a cyclic pointer structure — followed by ModifyPrompt(domain, prompt).
Common situations: A developer added a custom field (e.g. a logger interface or callback) to PromptConfig without a json:'-' tag or MarshalJSON implementation, then tried to save the prompt.
Related errors
- error unmarshalling project configuration: %v
- error marshalling project configuration: %v
- error unmarshalling footer config: %v
- error marshalling footer config: %v
- error marshalling default prompt config: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/d1f765f53d8a3d0d.
Report an issue: GitHub.