{"record":{"id":"4a9f1868440b1795","repo":"sipeed/picoclaw","slug":"deltachat-email-q-is-missing-a-chatmail-server","errorCode":null,"errorMessage":"deltachat: email %q is missing a chatmail server. Use %q or one of:\n%s","messagePattern":"deltachat: email %q is missing a chatmail server\\. Use %q or one of:\n(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/deltachat/deltachat.go","lineNumber":174,"sourceCode":"\tctx    context.Context\n\tcancel context.CancelFunc\n}\n\nfunc parseDeltaChatEmailSetting(value string) (string, bool, error) {\n\temail := strings.TrimSpace(value)\n\tif email == \"\" {\n\t\treturn \"\", false, fmt.Errorf(\n\t\t\t\"deltachat: email is required.\\nNext step: choose one of the chatmail servers below and set channel_list.deltachat.settings.email to %q, or use the same @server form with another chatmail relay. Run `picoclaw g` again; PicoClaw will create the account, print the generated full email address, and stop so you can save that address in the config.\\nAvailable chatmail servers:\\n%s\",\n\t\t\t\"@\"+defaultChatmailRelays[0].Domain,\n\t\t\tformatChatmailRelayList(),\n\t\t)\n\t}\n\tif !strings.HasPrefix(email, \"@\") {\n\t\treturn email, false, nil\n\t}\n\tdomain := strings.ToLower(strings.TrimSpace(strings.TrimPrefix(email, \"@\")))\n\tif domain == \"\" {\n\t\treturn \"\", false, fmt.Errorf(\"deltachat: email %q is missing a chatmail server. Use %q or one of:\\n%s\",\n\t\t\temail, \"@\"+defaultChatmailRelays[0].Domain, formatChatmailRelayList())\n\t}\n\tif strings.Contains(domain, \"@\") || strings.ContainsAny(domain, \"/\\\\ \\t\\r\\n\") {\n\t\treturn \"\", false, fmt.Errorf(\"deltachat: invalid chatmail server marker %q; use settings.email like %q\",\n\t\t\temail, \"@\"+defaultChatmailRelays[0].Domain)\n\t}\n\treturn domain, true, nil\n}\n\nfunc formatChatmailRelayList() string {\n\tvar b strings.Builder\n\tfor _, relay := range defaultChatmailRelays {\n\t\tfmt.Fprintf(&b, \"  @%-34s %s\\n\", relay.Domain, relay.Location)\n\t}\n\treturn strings.TrimRight(b.String(), \"\\n\")\n}\n\nfunc buildChatmailAccountQR(domain string) string {","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/deltachat/deltachat.go#L156-L192","documentation":"settings.email is exactly `@` (or `@   ` — an at-sign with only whitespace after trimming), so the chatmail-server marker form `@server` has no server part. The config parser strips the leading @, trims, and finds an empty domain; it tells you to use the default relay or one from the printed list.","triggerScenarios":"Setting channel_list.deltachat.settings.email to \"@\" intending to pick a server later; YAML value `\"@ \"` with trailing space; a templating step that substitutes an empty server variable into an `@${SERVER}` template.","commonSituations":"Config generated from a template where the server variable was empty; user misunderstanding `@server` syntax and writing just `@` as 'let the system choose'.","solutions":["Set email to `@` plus a concrete chatmail domain, e.g. `@nine.testrun.org`.","If templating, default the server variable (e.g. SERVER=${SERVER:-nine.testrun.org}) before rendering the config.","Or provide a full email address instead of the @server form."],"exampleFix":"# before\nsettings:\n  email: \"@\"\n\n# after\nsettings:\n  email: \"@nine.testrun.org\"","handlingStrategy":"validation","validationCode":"func validEmailSetting(v string) bool {\n    e := strings.TrimSpace(v)\n    if e == \"\" { return false }\n    if strings.HasPrefix(e, \"@\") {\n        d := strings.TrimSpace(strings.TrimPrefix(e, \"@\"))\n        return d != \"\"\n    }\n    return true\n}","typeGuard":"func validEmailSetting(v string) bool {\n    e := strings.TrimSpace(v)\n    if strings.HasPrefix(e, \"@\") {\n        return strings.TrimSpace(strings.TrimPrefix(e, \"@\")) != \"\"\n    }\n    return e != \"\"\n}","tryCatchPattern":"ch, err := deltachat.NewDeltaChatChannel(bc, cfg, bus)\nif err != nil && strings.Contains(err.Error(), \"missing a chatmail server\") {\n    return fmt.Errorf(\"finish the @server form, e.g. @nine.testrun.org\")\n}","preventionTips":["Default templated server variables instead of leaving them empty.","Lint config for email values that are just '@'.","Remember the accepted forms: full address or @domain — nothing else starts with @."],"tags":["deltachat","go","config","chatmail","validation"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}