{"record":{"id":"b27aa8f65aed6214","repo":"Tencent/WeKnora","slug":"w-config-is-nil","errorCode":null,"errorMessage":"%w: config is nil","messagePattern":"%w: config is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/datasource/connector/ima/types.go","lineNumber":59,"sourceCode":"}\n\n// GetBaseURL returns the normalized base URL (empty → default, no trailing slash).\nfunc (c *Config) GetBaseURL() string {\n\turl := strings.TrimSpace(c.BaseURL)\n\tif url == \"\" {\n\t\treturn DefaultBaseURL\n\t}\n\tif !strings.Contains(url, \"://\") {\n\t\turl = \"https://\" + url\n\t}\n\treturn strings.TrimRight(url, \"/\")\n}\n\n// parseIMAConfig extracts and validates IMA-specific configuration.\n// Uses JSON marshal/unmarshal roundtrip so extra fields are ignored gracefully.\nfunc parseIMAConfig(config *types.DataSourceConfig) (*Config, error) {\n\tif config == nil {\n\t\treturn nil, fmt.Errorf(\"%w: config is nil\", datasource.ErrInvalidConfig)\n\t}\n\tcredBytes, err := json.Marshal(config.Credentials)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"marshal credentials: %w\", err)\n\t}\n\tvar cfg Config\n\tif err := json.Unmarshal(credBytes, &cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse ima credentials: %w\", err)\n\t}\n\tif strings.TrimSpace(cfg.ClientID) == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: client_id is required\", datasource.ErrInvalidCredentials)\n\t}\n\tif strings.TrimSpace(cfg.APIKey) == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: api_key is required\", datasource.ErrInvalidCredentials)\n\t}\n\tif err := datasource.ValidateConnectorBaseURL(cfg.GetBaseURL()); err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/datasource/connector/ima/types.go#L41-L77","documentation":"parseIMAConfig in the IMA datasource connector rejects a nil *types.DataSourceConfig by wrapping datasource.ErrInvalidConfig. It is a fast-fail sentinel so callers (Validate, ListResources, walk) get a consistent, errors.Is-matchable error instead of a nil-pointer panic during the JSON marshal/unmarshal roundtrip of credentials.","triggerScenarios":"Calling Validate, ListResources, or walk on an IMA connector with a nil DataSourceConfig pointer; tests (TestParseIMAConfig_NilConfig) also trigger it intentionally. Practically this means the datasource was not loaded/registered before use, or a nil entry slipped into a collection of datasource configs.","commonSituations":"Config file missing the IMA datasource entry but code iterating all datasources regardless; a slice of configs containing a nil element; refactors returning nil, nil instead of an error from config loaders.","solutions":["Ensure the IMA DataSourceConfig is constructed and populated before calling connector methods","Skip or error on nil entries when iterating a slice of DataSourceConfig before invoking connectors","Use errors.Is(err, datasource.ErrInvalidConfig) to detect this case and return a clear 'datasource not configured' message to users"],"exampleFix":"// before\nfor _, cfg := range configs { // configs may contain nil\n    if err := connector.Validate(ctx, cfg); err != nil { ... }\n}\n// after\nfor _, cfg := range configs {\n    if cfg == nil {\n        return fmt.Errorf(\"datasource config is nil\");\n    }\n    if err := connector.Validate(ctx, cfg); err != nil { ... }\n}","handlingStrategy":"type-guard","validationCode":"if config == nil {\n    return fmt.Errorf(\"ima datasource not configured: DataSourceConfig is nil\")\n}\nif len(config.Credentials) == 0 {\n    return fmt.Errorf(\"ima datasource credentials are empty\")\n}","typeGuard":"func hasIMAConfig(cfg *types.DataSourceConfig) bool { return cfg != nil && cfg.Credentials != nil }","tryCatchPattern":"cfg, err := parseIMAConfig(config)\nif err != nil {\n    if errors.Is(err, datasource.ErrInvalidConfig) {\n        return fmt.Errorf(\"IMA datasource is not configured (nil DataSourceConfig); add it to your datasource config: %w\", err)\n    }\n    return err\n}","preventionTips":["Check for nil before adding DataSourceConfig entries to any slice/map iterated by connectors","Use errors.Is(err, datasource.ErrInvalidConfig) at call sites for clear user-facing messages","Make config loaders return an explicit error instead of (nil, nil) for missing datasources","Add a startup validation pass over all datasource configs, including the IMA connector's Validate"],"tags":["config-validation","nil-pointer","sentinel-error","datasource"],"backgroundTag":"invalid-configuration","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}