{"record":{"id":"259a6fea86e753ae","repo":"Tencent/WeKnora","slug":"w-api-key-must-be-a-non-empty-string","errorCode":null,"errorMessage":"%w: api_key must be a non-empty string","messagePattern":"%w: api_key must be a non-empty string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/datasource/connector/notion/types.go","lineNumber":45,"sourceCode":"\n// Config holds Notion-specific configuration for the data source connector.\ntype Config struct {\n\tAPIKey string `json:\"api_key\"` // Internal Integration Token\n}\n\n// parseNotionConfig extracts and validates Notion config from DataSourceConfig.\nfunc parseNotionConfig(config *types.DataSourceConfig) (*Config, error) {\n\tif config == nil {\n\t\treturn nil, datasource.ErrInvalidConfig\n\t}\n\n\ttokenVal, ok := config.Credentials[\"api_key\"]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%w: missing api_key\", datasource.ErrInvalidCredentials)\n\t}\n\ttoken, ok := tokenVal.(string)\n\tif !ok || token == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: api_key must be a non-empty string\", datasource.ErrInvalidCredentials)\n\t}\n\n\treturn &Config{APIKey: token}, nil\n}\n\n// --- API response types ---\n\n// notionPage represents a Notion page or database object.\ntype notionPage struct {\n\tID             string       `json:\"id\"`\n\tObject         string       `json:\"object\"` // \"page\" | \"database\" | \"data_source\" (2025-09-03+)\n\tParent         notionParent `json:\"parent\"`\n\tURL            string       `json:\"url\"`\n\tLastEditedTime time.Time    `json:\"last_edited_time\"`\n\tInTrash        bool         `json:\"in_trash\"`\n\t// Title is extracted from properties after unmarshaling; not directly from JSON.\n\tTitle string `json:\"-\"`\n\t// RawTitle holds the top-level title array (used by database objects).","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/datasource/connector/notion/types.go#L27-L63","documentation":"parseNotionConfig requires the \"api_key\" credential to be a non-empty string. If the value exists but is not a string, or is the empty string, the config is rejected with ErrInvalidCredentials wrapped with \"api_key must be a non-empty string\". This catches mistyped config values (e.g. numbers, nil) and blank tokens.","triggerScenarios":"config.Credentials[\"api_key\"] holds a non-string (e.g. nil from a YAML null, a number) or an empty string, passed to Validate/ListResources/FetchAll/FetchIncremental.","commonSituations":"Env var set to empty string (exported but blank), secret manager returning nil, config YAML with `api_key:` (empty value), quoting errors in config files.","solutions":["Set api_key to the full integration token string (starts with secret_)","Check the env var actually has a value: echo \"$NOTION_API_KEY\"","Fix config file syntax so api_key gets a real string value","Run Validate first to fail fast with this message"],"exampleFix":"// before\ntoken := os.Getenv(\"NOTION_API_KEY\") // may be \"\"\n// after\ntoken := os.Getenv(\"NOTION_API_KEY\")\nif token == \"\" {\n    log.Fatal(\"NOTION_API_KEY must be set\")\n}","handlingStrategy":"type-guard","validationCode":"token, ok := config.Credentials[\"api_key\"].(string); if !ok || token == \"\" { return errors.New(\"api_key must be a non-empty string\") }","typeGuard":"func validAPIKey(cfg *datasource.Config) bool {\n    if cfg == nil || cfg.Credentials == nil { return false }\n    s, ok := cfg.Credentials[\"api_key\"].(string)\n    return ok && strings.TrimSpace(s) != \"\"\n}","tryCatchPattern":"if err := connector.Validate(ctx, cfg); err != nil {\n    if errors.Is(err, datasource.ErrInvalidCredentials) && strings.Contains(err.Error(), \"non-empty string\") {\n        return errors.New(\"api_key is set but empty or wrong type\")\n    }\n    return err\n}","preventionTips":["Type-assert credentials before passing them to the connector","Trim whitespace; treat blank env vars as unset","Avoid YAML/JSON null or numeric values for api_key"],"tags":["notion","credentials","configuration","validation"],"backgroundTag":"invalid-credentials","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}