gastownhall/beads · error
Notion token not configured
Error message
Notion token not configured
What it means
The Client exists but its Token field is empty or whitespace-only, so doRequest aborts before building the HTTP request. Notion's API requires a Bearer integration token; the library fails fast with a clear message instead of receiving a 401 from the server. This is purely a local configuration check (strings.TrimSpace(c.Token) == "").
Source
Thrown at internal/notion/client.go:249
if err != nil {
return nil, fmt.Errorf("retrieve child data source %s: %w", resolvedID, err)
}
return &ResolvedDataSource{
InputID: identifier,
DataSourceID: resolvedID,
DataSource: resolvedDS,
Database: db,
ViewURL: strings.TrimSpace(ref),
}, nil
}
}
func (c *Client) doRequest(ctx context.Context, method, path string, requestBody interface{}) ([]byte, error) {
if c == nil {
return nil, fmt.Errorf("notion client is nil")
}
if strings.TrimSpace(c.Token) == "" {
return nil, fmt.Errorf("Notion token not configured")
}
httpClient := c.HTTPClient
if httpClient == nil {
httpClient = &http.Client{Timeout: DefaultTimeout}
}
var bodyReader io.Reader
if requestBody != nil {
payload, err := json.Marshal(requestBody)
if err != nil {
return nil, fmt.Errorf("marshal request body: %w", err)
}
bodyReader = bytes.NewReader(payload)
}
requestURL := path
if !strings.HasPrefix(requestURL, "http://") && !strings.HasPrefix(requestURL, "https://") {
requestURL = strings.TrimSuffix(c.BaseURL, "/") + pathView on GitHub (pinned to 71377f2769)
Solutions
- Export the token before running: export NOTION_TOKEN="ntn_..." (or set it in .env / deployment secrets).
- Pass the token explicitly to the client constructor and log a startup error if it is empty.
- Validate configuration at startup: if strings.TrimSpace(cfg.NotionToken) == "" { return errors.New("NOTION_TOKEN is required") }.
- Verify the secret is actually mounted in the runtime environment (docker inspect / kubectl describe pod), not just present locally.
Example fix
// before
client := notion.NewClient(os.Getenv("NOTION_TOKEN")) // silently empty
// after
token := os.Getenv("NOTION_TOKEN")
if strings.TrimSpace(token) == "" {
return fmt.Errorf("NOTION_TOKEN must be set")
}
client := notion.NewClient(token) Defensive patterns
Strategy: validation
Validate before calling
token := os.Getenv("NOTION_TOKEN")
if strings.TrimSpace(token) == "" {
return fmt.Errorf("NOTION_TOKEN is required")
} Try / catch
if err != nil && strings.Contains(err.Error(), "Notion token not configured") {
log.Fatal("set NOTION_TOKEN in your environment")
} Prevention
- Validate required env/config at process startup with fail-fast checks.
- Use a config-loading library that reports missing keys instead of defaulting to empty strings.
- Keep secrets out of code; document required env vars in README/CI setup.
When it happens
Trigger: Client constructed with an empty token: notion.NewClient("") or NewClient(os.Getenv("NOTION_TOKEN")) when NOTION_TOKEN is unset/empty; a config struct unmarshaled without the token key; token set only to spaces via env or config file.
Common situations: Missing NOTION_TOKEN env var in CI or .env not loaded; YAML/JSON config missing the notion.token key so it unmarshals as ""; Docker container deployed without the secret injected; renaming the env var without updating the loader.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Jira API token not configured Run: bd config set jira.api_to
- Linear authentication not configured Options: OAuth (for C
- Linear authentication not configured Options: OAuth (for C
- Azure DevOps PAT not configured (set ado.pat or AZURE_DEVOPS
- Jira API token not configured (set jira.api_token or JIRA_AP
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9dd5cb0fdf827ad5.
Report an issue: GitHub.